InlineCost.h 14 KB

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