Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===- llvm/Analysis/ProfileSummaryInfo.h - profile summary ---*- 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 contains a pass that provides access to profile summary
  10. // information.
  11. //
  12. //===----------------------------------------------------------------------===//
  13.  
  14. #ifndef LLVM_ANALYSIS_PROFILESUMMARYINFO_H
  15. #define LLVM_ANALYSIS_PROFILESUMMARYINFO_H
  16.  
  17. #include "llvm/ADT/DenseMap.h"
  18. #include "llvm/IR/PassManager.h"
  19. #include "llvm/IR/ProfileSummary.h"
  20. #include "llvm/Pass.h"
  21. #include <memory>
  22. #include <optional>
  23.  
  24. namespace llvm {
  25. class BasicBlock;
  26. class BlockFrequencyInfo;
  27. class CallBase;
  28. class Function;
  29.  
  30. /// Analysis providing profile information.
  31. ///
  32. /// This is an immutable analysis pass that provides ability to query global
  33. /// (program-level) profile information. The main APIs are isHotCount and
  34. /// isColdCount that tells whether a given profile count is considered hot/cold
  35. /// based on the profile summary. This also provides convenience methods to
  36. /// check whether a function is hot or cold.
  37.  
  38. // FIXME: Provide convenience methods to determine hotness/coldness of other IR
  39. // units. This would require making this depend on BFI.
  40. class ProfileSummaryInfo {
  41. private:
  42.   const Module *M;
  43.   std::unique_ptr<ProfileSummary> Summary;
  44.   void computeThresholds();
  45.   // Count thresholds to answer isHotCount and isColdCount queries.
  46.   std::optional<uint64_t> HotCountThreshold, ColdCountThreshold;
  47.   // True if the working set size of the code is considered huge,
  48.   // because the number of profile counts required to reach the hot
  49.   // percentile is above a huge threshold.
  50.   std::optional<bool> HasHugeWorkingSetSize;
  51.   // True if the working set size of the code is considered large,
  52.   // because the number of profile counts required to reach the hot
  53.   // percentile is above a large threshold.
  54.   std::optional<bool> HasLargeWorkingSetSize;
  55.   // Compute the threshold for a given cutoff.
  56.   std::optional<uint64_t> computeThreshold(int PercentileCutoff) const;
  57.   // The map that caches the threshold values. The keys are the percentile
  58.   // cutoff values and the values are the corresponding threshold values.
  59.   mutable DenseMap<int, uint64_t> ThresholdCache;
  60.  
  61. public:
  62.   ProfileSummaryInfo(const Module &M) : M(&M) { refresh(); }
  63.   ProfileSummaryInfo(ProfileSummaryInfo &&Arg) = default;
  64.  
  65.   /// If no summary is present, attempt to refresh.
  66.   void refresh();
  67.  
  68.   /// Returns true if profile summary is available.
  69.   bool hasProfileSummary() const { return Summary != nullptr; }
  70.  
  71.   /// Returns true if module \c M has sample profile.
  72.   bool hasSampleProfile() const {
  73.     return hasProfileSummary() &&
  74.            Summary->getKind() == ProfileSummary::PSK_Sample;
  75.   }
  76.  
  77.   /// Returns true if module \c M has instrumentation profile.
  78.   bool hasInstrumentationProfile() const {
  79.     return hasProfileSummary() &&
  80.            Summary->getKind() == ProfileSummary::PSK_Instr;
  81.   }
  82.  
  83.   /// Returns true if module \c M has context sensitive instrumentation profile.
  84.   bool hasCSInstrumentationProfile() const {
  85.     return hasProfileSummary() &&
  86.            Summary->getKind() == ProfileSummary::PSK_CSInstr;
  87.   }
  88.  
  89.   /// Handle the invalidation of this information.
  90.   ///
  91.   /// When used as a result of \c ProfileSummaryAnalysis this method will be
  92.   /// called when the module this was computed for changes. Since profile
  93.   /// summary is immutable after it is annotated on the module, we return false
  94.   /// here.
  95.   bool invalidate(Module &, const PreservedAnalyses &,
  96.                   ModuleAnalysisManager::Invalidator &) {
  97.     return false;
  98.   }
  99.  
  100.   /// Returns the profile count for \p CallInst.
  101.   std::optional<uint64_t> getProfileCount(const CallBase &CallInst,
  102.                                           BlockFrequencyInfo *BFI,
  103.                                           bool AllowSynthetic = false) const;
  104.   /// Returns true if module \c M has partial-profile sample profile.
  105.   bool hasPartialSampleProfile() const;
  106.   /// Returns true if the working set size of the code is considered huge.
  107.   bool hasHugeWorkingSetSize() const;
  108.   /// Returns true if the working set size of the code is considered large.
  109.   bool hasLargeWorkingSetSize() const;
  110.   /// Returns true if \p F has hot function entry.
  111.   bool isFunctionEntryHot(const Function *F) const;
  112.   /// Returns true if \p F contains hot code.
  113.   bool isFunctionHotInCallGraph(const Function *F,
  114.                                 BlockFrequencyInfo &BFI) const;
  115.   /// Returns true if \p F has cold function entry.
  116.   bool isFunctionEntryCold(const Function *F) const;
  117.   /// Returns true if \p F contains only cold code.
  118.   bool isFunctionColdInCallGraph(const Function *F,
  119.                                  BlockFrequencyInfo &BFI) const;
  120.   /// Returns true if the hotness of \p F is unknown.
  121.   bool isFunctionHotnessUnknown(const Function &F) const;
  122.   /// Returns true if \p F contains hot code with regard to a given hot
  123.   /// percentile cutoff value.
  124.   bool isFunctionHotInCallGraphNthPercentile(int PercentileCutoff,
  125.                                              const Function *F,
  126.                                              BlockFrequencyInfo &BFI) const;
  127.   /// Returns true if \p F contains cold code with regard to a given cold
  128.   /// percentile cutoff value.
  129.   bool isFunctionColdInCallGraphNthPercentile(int PercentileCutoff,
  130.                                               const Function *F,
  131.                                               BlockFrequencyInfo &BFI) const;
  132.   /// Returns true if count \p C is considered hot.
  133.   bool isHotCount(uint64_t C) const;
  134.   /// Returns true if count \p C is considered cold.
  135.   bool isColdCount(uint64_t C) const;
  136.   /// Returns true if count \p C is considered hot with regard to a given
  137.   /// hot percentile cutoff value.
  138.   /// PercentileCutoff is encoded as a 6 digit decimal fixed point number, where
  139.   /// the first two digits are the whole part. E.g. 995000 for 99.5 percentile.
  140.   bool isHotCountNthPercentile(int PercentileCutoff, uint64_t C) const;
  141.   /// Returns true if count \p C is considered cold with regard to a given
  142.   /// cold percentile cutoff value.
  143.   /// PercentileCutoff is encoded as a 6 digit decimal fixed point number, where
  144.   /// the first two digits are the whole part. E.g. 995000 for 99.5 percentile.
  145.   bool isColdCountNthPercentile(int PercentileCutoff, uint64_t C) const;
  146.   /// Returns true if BasicBlock \p BB is considered hot.
  147.   bool isHotBlock(const BasicBlock *BB, BlockFrequencyInfo *BFI) const;
  148.   /// Returns true if BasicBlock \p BB is considered cold.
  149.   bool isColdBlock(const BasicBlock *BB, BlockFrequencyInfo *BFI) const;
  150.   /// Returns true if BasicBlock \p BB is considered hot with regard to a given
  151.   /// hot percentile cutoff value.
  152.   /// PercentileCutoff is encoded as a 6 digit decimal fixed point number, where
  153.   /// the first two digits are the whole part. E.g. 995000 for 99.5 percentile.
  154.   bool isHotBlockNthPercentile(int PercentileCutoff, const BasicBlock *BB,
  155.                                BlockFrequencyInfo *BFI) const;
  156.   /// Returns true if BasicBlock \p BB is considered cold with regard to a given
  157.   /// cold percentile cutoff value.
  158.   /// PercentileCutoff is encoded as a 6 digit decimal fixed point number, where
  159.   /// the first two digits are the whole part. E.g. 995000 for 99.5 percentile.
  160.   bool isColdBlockNthPercentile(int PercentileCutoff, const BasicBlock *BB,
  161.                                 BlockFrequencyInfo *BFI) const;
  162.   /// Returns true if the call site \p CB is considered hot.
  163.   bool isHotCallSite(const CallBase &CB, BlockFrequencyInfo *BFI) const;
  164.   /// Returns true if call site \p CB is considered cold.
  165.   bool isColdCallSite(const CallBase &CB, BlockFrequencyInfo *BFI) const;
  166.   /// Returns HotCountThreshold if set. Recompute HotCountThreshold
  167.   /// if not set.
  168.   uint64_t getOrCompHotCountThreshold() const;
  169.   /// Returns ColdCountThreshold if set. Recompute HotCountThreshold
  170.   /// if not set.
  171.   uint64_t getOrCompColdCountThreshold() const;
  172.   /// Returns HotCountThreshold if set.
  173.   uint64_t getHotCountThreshold() const {
  174.     return HotCountThreshold.value_or(0);
  175.   }
  176.   /// Returns ColdCountThreshold if set.
  177.   uint64_t getColdCountThreshold() const {
  178.     return ColdCountThreshold.value_or(0);
  179.   }
  180.  
  181.  private:
  182.    template <bool isHot>
  183.    bool isFunctionHotOrColdInCallGraphNthPercentile(
  184.        int PercentileCutoff, const Function *F, BlockFrequencyInfo &BFI) const;
  185.    template <bool isHot>
  186.    bool isHotOrColdCountNthPercentile(int PercentileCutoff, uint64_t C) const;
  187.    template <bool isHot>
  188.    bool isHotOrColdBlockNthPercentile(int PercentileCutoff,
  189.                                       const BasicBlock *BB,
  190.                                       BlockFrequencyInfo *BFI) const;
  191. };
  192.  
  193. /// An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
  194. class ProfileSummaryInfoWrapperPass : public ImmutablePass {
  195.   std::unique_ptr<ProfileSummaryInfo> PSI;
  196.  
  197. public:
  198.   static char ID;
  199.   ProfileSummaryInfoWrapperPass();
  200.  
  201.   ProfileSummaryInfo &getPSI() { return *PSI; }
  202.   const ProfileSummaryInfo &getPSI() const { return *PSI; }
  203.  
  204.   bool doInitialization(Module &M) override;
  205.   bool doFinalization(Module &M) override;
  206.   void getAnalysisUsage(AnalysisUsage &AU) const override {
  207.     AU.setPreservesAll();
  208.   }
  209. };
  210.  
  211. /// An analysis pass based on the new PM to deliver ProfileSummaryInfo.
  212. class ProfileSummaryAnalysis
  213.     : public AnalysisInfoMixin<ProfileSummaryAnalysis> {
  214. public:
  215.   typedef ProfileSummaryInfo Result;
  216.  
  217.   Result run(Module &M, ModuleAnalysisManager &);
  218.  
  219. private:
  220.   friend AnalysisInfoMixin<ProfileSummaryAnalysis>;
  221.   static AnalysisKey Key;
  222. };
  223.  
  224. /// Printer pass that uses \c ProfileSummaryAnalysis.
  225. class ProfileSummaryPrinterPass
  226.     : public PassInfoMixin<ProfileSummaryPrinterPass> {
  227.   raw_ostream &OS;
  228.  
  229. public:
  230.   explicit ProfileSummaryPrinterPass(raw_ostream &OS) : OS(OS) {}
  231.   PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
  232. };
  233.  
  234. } // end namespace llvm
  235.  
  236. #endif
  237.