1 //===- InlineCost.h - Cost analysis for inliner -----------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements heuristics for inlining decisions. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_ANALYSIS_INLINECOST_H 14 #define LLVM_ANALYSIS_INLINECOST_H 15 16 #include "llvm/ADT/APInt.h" 17 #include "llvm/ADT/STLFunctionalExtras.h" 18 #include "llvm/Analysis/InlineModelFeatureMaps.h" 19 #include "llvm/IR/PassManager.h" 20 #include "llvm/Support/Compiler.h" 21 #include <cassert> 22 #include <climits> 23 #include <optional> 24 25 namespace llvm { 26 class AssumptionCache; 27 class OptimizationRemarkEmitter; 28 class BlockFrequencyInfo; 29 class CallBase; 30 class DataLayout; 31 class Function; 32 class ProfileSummaryInfo; 33 class TargetTransformInfo; 34 class TargetLibraryInfo; 35 class EphemeralValuesCache; 36 37 namespace InlineConstants { 38 // Various thresholds used by inline cost analysis. 39 /// Use when optsize (-Os) is specified. 40 const int OptSizeThreshold = 50; 41 42 /// Use when minsize (-Oz) is specified. 43 const int OptMinSizeThreshold = 5; 44 45 /// Use when -O3 is specified. 46 const int OptAggressiveThreshold = 250; 47 48 // Various magic constants used to adjust heuristics. 49 LLVM_ABI int getInstrCost(); 50 const int IndirectCallThreshold = 100; 51 const int LoopPenalty = 25; 52 const int ColdccPenalty = 2000; 53 /// Do not inline functions which allocate this many bytes on the stack 54 /// when the caller is recursive. 55 const unsigned TotalAllocaSizeRecursiveCaller = 1024; 56 /// Do not inline dynamic allocas that have been constant propagated to be 57 /// static allocas above this amount in bytes. 58 const uint64_t MaxSimplifiedDynamicAllocaToInline = 65536; 59 60 const char FunctionInlineCostMultiplierAttributeName[] = 61 "function-inline-cost-multiplier"; 62 63 const char MaxInlineStackSizeAttributeName[] = "inline-max-stacksize"; 64 } // namespace InlineConstants 65 66 // The cost-benefit pair computed by cost-benefit analysis. 67 class CostBenefitPair { 68 public: CostBenefitPair(APInt Cost,APInt Benefit)69 CostBenefitPair(APInt Cost, APInt Benefit) 70 : Cost(std::move(Cost)), Benefit(std::move(Benefit)) {} 71 getCost()72 const APInt &getCost() const { return Cost; } 73 getBenefit()74 const APInt &getBenefit() const { return Benefit; } 75 76 private: 77 APInt Cost; 78 APInt Benefit; 79 }; 80 81 /// Represents the cost of inlining a function. 82 /// 83 /// This supports special values for functions which should "always" or 84 /// "never" be inlined. Otherwise, the cost represents a unitless amount; 85 /// smaller values increase the likelihood of the function being inlined. 86 /// 87 /// Objects of this type also provide the adjusted threshold for inlining 88 /// based on the information available for a particular callsite. They can be 89 /// directly tested to determine if inlining should occur given the cost and 90 /// threshold for this cost metric. 91 class InlineCost { 92 enum SentinelValues { AlwaysInlineCost = INT_MIN, NeverInlineCost = INT_MAX }; 93 94 /// The estimated cost of inlining this callsite. 95 int Cost = 0; 96 97 /// The adjusted threshold against which this cost was computed. 98 int Threshold = 0; 99 100 /// The amount of StaticBonus that has been applied. 101 int StaticBonusApplied = 0; 102 103 /// Must be set for Always and Never instances. 104 const char *Reason = nullptr; 105 106 /// The cost-benefit pair computed by cost-benefit analysis. 107 std::optional<CostBenefitPair> CostBenefit; 108 109 // Trivial constructor, interesting logic in the factory functions below. 110 InlineCost(int Cost, int Threshold, int StaticBonusApplied, 111 const char *Reason = nullptr, 112 std::optional<CostBenefitPair> CostBenefit = std::nullopt) Cost(Cost)113 : Cost(Cost), Threshold(Threshold), 114 StaticBonusApplied(StaticBonusApplied), Reason(Reason), 115 CostBenefit(CostBenefit) { 116 assert((isVariable() || Reason) && 117 "Reason must be provided for Never or Always"); 118 } 119 120 public: 121 static InlineCost get(int Cost, int Threshold, int StaticBonus = 0) { 122 assert(Cost > AlwaysInlineCost && "Cost crosses sentinel value"); 123 assert(Cost < NeverInlineCost && "Cost crosses sentinel value"); 124 return InlineCost(Cost, Threshold, StaticBonus); 125 } 126 static InlineCost 127 getAlways(const char *Reason, 128 std::optional<CostBenefitPair> CostBenefit = std::nullopt) { 129 return InlineCost(AlwaysInlineCost, 0, 0, Reason, CostBenefit); 130 } 131 static InlineCost 132 getNever(const char *Reason, 133 std::optional<CostBenefitPair> CostBenefit = std::nullopt) { 134 return InlineCost(NeverInlineCost, 0, 0, Reason, CostBenefit); 135 } 136 137 /// Test whether the inline cost is low enough for inlining. 138 explicit operator bool() const { return Cost < Threshold; } 139 isAlways()140 bool isAlways() const { return Cost == AlwaysInlineCost; } isNever()141 bool isNever() const { return Cost == NeverInlineCost; } isVariable()142 bool isVariable() const { return !isAlways() && !isNever(); } 143 144 /// Get the inline cost estimate. 145 /// It is an error to call this on an "always" or "never" InlineCost. getCost()146 int getCost() const { 147 assert(isVariable() && "Invalid access of InlineCost"); 148 return Cost; 149 } 150 151 /// Get the threshold against which the cost was computed getThreshold()152 int getThreshold() const { 153 assert(isVariable() && "Invalid access of InlineCost"); 154 return Threshold; 155 } 156 157 /// Get the amount of StaticBonus applied. getStaticBonusApplied()158 int getStaticBonusApplied() const { 159 assert(isVariable() && "Invalid access of InlineCost"); 160 return StaticBonusApplied; 161 } 162 163 /// Get the cost-benefit pair which was computed by cost-benefit analysis getCostBenefit()164 std::optional<CostBenefitPair> getCostBenefit() const { return CostBenefit; } 165 166 /// Get the reason of Always or Never. getReason()167 const char *getReason() const { 168 assert((Reason || isVariable()) && 169 "InlineCost reason must be set for Always or Never"); 170 return Reason; 171 } 172 173 /// Get the cost delta from the threshold for inlining. 174 /// Only valid if the cost is of the variable kind. Returns a negative 175 /// value if the cost is too high to inline. getCostDelta()176 int getCostDelta() const { return Threshold - getCost(); } 177 }; 178 179 /// InlineResult is basically true or false. For false results the message 180 /// describes a reason. 181 class InlineResult { 182 const char *Message = nullptr; Message(Message)183 InlineResult(const char *Message = nullptr) : Message(Message) {} 184 185 public: success()186 static InlineResult success() { return {}; } failure(const char * Reason)187 static InlineResult failure(const char *Reason) { 188 return InlineResult(Reason); 189 } isSuccess()190 bool isSuccess() const { return Message == nullptr; } getFailureReason()191 const char *getFailureReason() const { 192 assert(!isSuccess() && 193 "getFailureReason should only be called in failure cases"); 194 return Message; 195 } 196 }; 197 198 /// Thresholds to tune inline cost analysis. The inline cost analysis decides 199 /// the condition to apply a threshold and applies it. Otherwise, 200 /// DefaultThreshold is used. If a threshold is Optional, it is applied only 201 /// when it has a valid value. Typically, users of inline cost analysis 202 /// obtain an InlineParams object through one of the \c getInlineParams methods 203 /// and pass it to \c getInlineCost. Some specialized versions of inliner 204 /// (such as the pre-inliner) might have custom logic to compute \c InlineParams 205 /// object. 206 207 struct InlineParams { 208 /// The default threshold to start with for a callee. 209 int DefaultThreshold = -1; 210 211 /// Threshold to use for callees with inline hint. 212 std::optional<int> HintThreshold; 213 214 /// Threshold to use for cold callees. 215 std::optional<int> ColdThreshold; 216 217 /// Threshold to use when the caller is optimized for size. 218 std::optional<int> OptSizeThreshold; 219 220 /// Threshold to use when the caller is optimized for minsize. 221 std::optional<int> OptMinSizeThreshold; 222 223 /// Threshold to use when the callsite is considered hot. 224 std::optional<int> HotCallSiteThreshold; 225 226 /// Threshold to use when the callsite is considered hot relative to function 227 /// entry. 228 std::optional<int> LocallyHotCallSiteThreshold; 229 230 /// Threshold to use when the callsite is considered cold. 231 std::optional<int> ColdCallSiteThreshold; 232 233 /// Compute inline cost even when the cost has exceeded the threshold. 234 std::optional<bool> ComputeFullInlineCost; 235 236 /// Indicate whether we should allow inline deferral. 237 std::optional<bool> EnableDeferral; 238 239 /// Indicate whether we allow inlining for recursive call. 240 std::optional<bool> AllowRecursiveCall = false; 241 }; 242 243 LLVM_ABI std::optional<int> getStringFnAttrAsInt(CallBase &CB, 244 StringRef AttrKind); 245 246 /// Generate the parameters to tune the inline cost analysis based only on the 247 /// commandline options. 248 LLVM_ABI InlineParams getInlineParams(); 249 250 /// Generate the parameters to tune the inline cost analysis based on command 251 /// line options. If -inline-threshold option is not explicitly passed, 252 /// \p Threshold is used as the default threshold. 253 LLVM_ABI InlineParams getInlineParams(int Threshold); 254 255 /// Generate the parameters to tune the inline cost analysis based on command 256 /// line options. If -inline-threshold option is not explicitly passed, 257 /// the default threshold is computed from \p OptLevel and \p SizeOptLevel. 258 /// An \p OptLevel value above 3 is considered an aggressive optimization mode. 259 /// \p SizeOptLevel of 1 corresponds to the -Os flag and 2 corresponds to 260 /// the -Oz flag. 261 LLVM_ABI InlineParams getInlineParams(unsigned OptLevel, unsigned SizeOptLevel); 262 263 /// Return the cost associated with a callsite, including parameter passing 264 /// and the call/return instruction. 265 LLVM_ABI int getCallsiteCost(const TargetTransformInfo &TTI, 266 const CallBase &Call, const DataLayout &DL); 267 268 /// Get an InlineCost object representing the cost of inlining this 269 /// callsite. 270 /// 271 /// Note that a default threshold is passed into this function. This threshold 272 /// could be modified based on callsite's properties and only costs below this 273 /// new threshold are computed with any accuracy. The new threshold can be 274 /// used to bound the computation necessary to determine whether the cost is 275 /// sufficiently low to warrant inlining. 276 /// 277 /// Also note that calling this function *dynamically* computes the cost of 278 /// inlining the callsite. It is an expensive, heavyweight call. 279 LLVM_ABI InlineCost getInlineCost( 280 CallBase &Call, const InlineParams &Params, TargetTransformInfo &CalleeTTI, 281 function_ref<AssumptionCache &(Function &)> GetAssumptionCache, 282 function_ref<const TargetLibraryInfo &(Function &)> GetTLI, 283 function_ref<BlockFrequencyInfo &(Function &)> GetBFI = nullptr, 284 ProfileSummaryInfo *PSI = nullptr, OptimizationRemarkEmitter *ORE = nullptr, 285 function_ref<EphemeralValuesCache &(Function &)> GetEphValuesCache = 286 nullptr); 287 288 /// Get an InlineCost with the callee explicitly specified. 289 /// This allows you to calculate the cost of inlining a function via a 290 /// pointer. This behaves exactly as the version with no explicit callee 291 /// parameter in all other respects. 292 // 293 LLVM_ABI InlineCost getInlineCost( 294 CallBase &Call, Function *Callee, const InlineParams &Params, 295 TargetTransformInfo &CalleeTTI, 296 function_ref<AssumptionCache &(Function &)> GetAssumptionCache, 297 function_ref<const TargetLibraryInfo &(Function &)> GetTLI, 298 function_ref<BlockFrequencyInfo &(Function &)> GetBFI = nullptr, 299 ProfileSummaryInfo *PSI = nullptr, OptimizationRemarkEmitter *ORE = nullptr, 300 function_ref<EphemeralValuesCache &(Function &)> GetEphValuesCache = 301 nullptr); 302 303 /// Returns InlineResult::success() if the call site should be always inlined 304 /// because of user directives, and the inlining is viable. Returns 305 /// InlineResult::failure() if the inlining may never happen because of user 306 /// directives or incompatibilities detectable without needing callee traversal. 307 /// Otherwise returns std::nullopt, meaning that inlining should be decided 308 /// based on other criteria (e.g. cost modeling). 309 LLVM_ABI std::optional<InlineResult> getAttributeBasedInliningDecision( 310 CallBase &Call, Function *Callee, TargetTransformInfo &CalleeTTI, 311 function_ref<const TargetLibraryInfo &(Function &)> GetTLI); 312 313 /// Get the cost estimate ignoring thresholds. This is similar to getInlineCost 314 /// when passed InlineParams::ComputeFullInlineCost, or a non-null ORE. It 315 /// uses default InlineParams otherwise. 316 /// Contrary to getInlineCost, which makes a threshold-based final evaluation of 317 /// should/shouldn't inline, captured in InlineResult, getInliningCostEstimate 318 /// returns: 319 /// - std::nullopt, if the inlining cannot happen (is illegal) 320 /// - an integer, representing the cost. 321 LLVM_ABI std::optional<int> getInliningCostEstimate( 322 CallBase &Call, TargetTransformInfo &CalleeTTI, 323 function_ref<AssumptionCache &(Function &)> GetAssumptionCache, 324 function_ref<BlockFrequencyInfo &(Function &)> GetBFI = nullptr, 325 function_ref<const TargetLibraryInfo &(Function &)> GetTLI = nullptr, 326 ProfileSummaryInfo *PSI = nullptr, 327 OptimizationRemarkEmitter *ORE = nullptr); 328 329 /// Get the expanded cost features. The features are returned unconditionally, 330 /// even if inlining is impossible. 331 LLVM_ABI std::optional<InlineCostFeatures> getInliningCostFeatures( 332 CallBase &Call, TargetTransformInfo &CalleeTTI, 333 function_ref<AssumptionCache &(Function &)> GetAssumptionCache, 334 function_ref<BlockFrequencyInfo &(Function &)> GetBFI = nullptr, 335 function_ref<const TargetLibraryInfo &(Function &)> GetTLI = nullptr, 336 ProfileSummaryInfo *PSI = nullptr, 337 OptimizationRemarkEmitter *ORE = nullptr); 338 339 /// Minimal filter to detect invalid constructs for inlining. 340 LLVM_ABI InlineResult isInlineViable(Function &Callee); 341 342 // This pass is used to annotate instructions during the inline process for 343 // debugging and analysis. The main purpose of the pass is to see and test 344 // inliner's decisions when creating new optimizations to InlineCost. 345 struct InlineCostAnnotationPrinterPass 346 : PassInfoMixin<InlineCostAnnotationPrinterPass> { 347 raw_ostream &OS; 348 349 public: InlineCostAnnotationPrinterPassInlineCostAnnotationPrinterPass350 explicit InlineCostAnnotationPrinterPass(raw_ostream &OS) : OS(OS) {} 351 LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM); isRequiredInlineCostAnnotationPrinterPass352 static bool isRequired() { return true; } 353 }; 354 } // namespace llvm 355 356 #endif 357