InlineCost.h 13 KB

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