Home | History | Annotate | Download | only in Analysis
      1 //===- llvm/Analysis/ProfileSummaryInfo.h - profile summary ---*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file contains a pass that provides access to profile summary
     11 // information.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_ANALYSIS_PROFILE_SUMMARY_INFO_H
     16 #define LLVM_ANALYSIS_PROFILE_SUMMARY_INFO_H
     17 
     18 #include "llvm/ADT/ArrayRef.h"
     19 #include "llvm/ADT/DenseMap.h"
     20 #include "llvm/ADT/SmallSet.h"
     21 #include "llvm/IR/Function.h"
     22 #include "llvm/IR/Instructions.h"
     23 #include "llvm/IR/PassManager.h"
     24 #include "llvm/IR/ProfileSummary.h"
     25 #include "llvm/IR/ValueHandle.h"
     26 #include "llvm/Pass.h"
     27 #include <memory>
     28 
     29 namespace llvm {
     30 class BasicBlock;
     31 class BlockFrequencyInfo;
     32 class CallSite;
     33 class ProfileSummary;
     34 /// Analysis providing profile information.
     35 ///
     36 /// This is an immutable analysis pass that provides ability to query global
     37 /// (program-level) profile information. The main APIs are isHotCount and
     38 /// isColdCount that tells whether a given profile count is considered hot/cold
     39 /// based on the profile summary. This also provides convenience methods to
     40 /// check whether a function is hot or cold.
     41 
     42 // FIXME: Provide convenience methods to determine hotness/coldness of other IR
     43 // units. This would require making this depend on BFI.
     44 class ProfileSummaryInfo {
     45 private:
     46   Module &M;
     47   std::unique_ptr<ProfileSummary> Summary;
     48   bool computeSummary();
     49   void computeThresholds();
     50   // Count thresholds to answer isHotCount and isColdCount queries.
     51   Optional<uint64_t> HotCountThreshold, ColdCountThreshold;
     52   // True if the working set size of the code is considered huge,
     53   // because the number of profile counts required to reach the hot
     54   // percentile is above a huge threshold.
     55   Optional<bool> HasHugeWorkingSetSize;
     56 
     57 public:
     58   ProfileSummaryInfo(Module &M) : M(M) {}
     59   ProfileSummaryInfo(ProfileSummaryInfo &&Arg)
     60       : M(Arg.M), Summary(std::move(Arg.Summary)) {}
     61 
     62   /// Returns true if profile summary is available.
     63   bool hasProfileSummary() { return computeSummary(); }
     64 
     65   /// Returns true if module \c M has sample profile.
     66   bool hasSampleProfile() {
     67     return hasProfileSummary() &&
     68            Summary->getKind() == ProfileSummary::PSK_Sample;
     69   }
     70 
     71   /// Returns true if module \c M has instrumentation profile.
     72   bool hasInstrumentationProfile() {
     73     return hasProfileSummary() &&
     74            Summary->getKind() == ProfileSummary::PSK_Instr;
     75   }
     76 
     77   /// Handle the invalidation of this information.
     78   ///
     79   /// When used as a result of \c ProfileSummaryAnalysis this method will be
     80   /// called when the module this was computed for changes. Since profile
     81   /// summary is immutable after it is annotated on the module, we return false
     82   /// here.
     83   bool invalidate(Module &, const PreservedAnalyses &,
     84                   ModuleAnalysisManager::Invalidator &) {
     85     return false;
     86   }
     87 
     88   /// Returns the profile count for \p CallInst.
     89   Optional<uint64_t> getProfileCount(const Instruction *CallInst,
     90                                      BlockFrequencyInfo *BFI);
     91   /// Returns true if the working set size of the code is considered huge.
     92   bool hasHugeWorkingSetSize();
     93   /// Returns true if \p F has hot function entry.
     94   bool isFunctionEntryHot(const Function *F);
     95   /// Returns true if \p F contains hot code.
     96   bool isFunctionHotInCallGraph(const Function *F, BlockFrequencyInfo &BFI);
     97   /// Returns true if \p F has cold function entry.
     98   bool isFunctionEntryCold(const Function *F);
     99   /// Returns true if \p F contains only cold code.
    100   bool isFunctionColdInCallGraph(const Function *F, BlockFrequencyInfo &BFI);
    101   /// Returns true if \p F is a hot function.
    102   bool isHotCount(uint64_t C);
    103   /// Returns true if count \p C is considered cold.
    104   bool isColdCount(uint64_t C);
    105   /// Returns true if BasicBlock \p B is considered hot.
    106   bool isHotBB(const BasicBlock *B, BlockFrequencyInfo *BFI);
    107   /// Returns true if BasicBlock \p B is considered cold.
    108   bool isColdBB(const BasicBlock *B, BlockFrequencyInfo *BFI);
    109   /// Returns true if CallSite \p CS is considered hot.
    110   bool isHotCallSite(const CallSite &CS, BlockFrequencyInfo *BFI);
    111   /// Returns true if Callsite \p CS is considered cold.
    112   bool isColdCallSite(const CallSite &CS, BlockFrequencyInfo *BFI);
    113   /// Returns HotCountThreshold if set. Recompute HotCountThreshold
    114   /// if not set.
    115   uint64_t getOrCompHotCountThreshold();
    116   /// Returns ColdCountThreshold if set. Recompute HotCountThreshold
    117   /// if not set.
    118   uint64_t getOrCompColdCountThreshold();
    119   /// Returns HotCountThreshold if set.
    120   uint64_t getHotCountThreshold() {
    121     return HotCountThreshold ? HotCountThreshold.getValue() : 0;
    122   }
    123   /// Returns ColdCountThreshold if set.
    124   uint64_t getColdCountThreshold() {
    125     return ColdCountThreshold ? ColdCountThreshold.getValue() : 0;
    126   }
    127 };
    128 
    129 /// An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
    130 class ProfileSummaryInfoWrapperPass : public ImmutablePass {
    131   std::unique_ptr<ProfileSummaryInfo> PSI;
    132 
    133 public:
    134   static char ID;
    135   ProfileSummaryInfoWrapperPass();
    136 
    137   ProfileSummaryInfo *getPSI() {
    138     return &*PSI;
    139   }
    140 
    141   bool doInitialization(Module &M) override;
    142   bool doFinalization(Module &M) override;
    143   void getAnalysisUsage(AnalysisUsage &AU) const override {
    144     AU.setPreservesAll();
    145   }
    146 };
    147 
    148 /// An analysis pass based on the new PM to deliver ProfileSummaryInfo.
    149 class ProfileSummaryAnalysis
    150     : public AnalysisInfoMixin<ProfileSummaryAnalysis> {
    151 public:
    152   typedef ProfileSummaryInfo Result;
    153 
    154   Result run(Module &M, ModuleAnalysisManager &);
    155 
    156 private:
    157   friend AnalysisInfoMixin<ProfileSummaryAnalysis>;
    158   static AnalysisKey Key;
    159 };
    160 
    161 /// Printer pass that uses \c ProfileSummaryAnalysis.
    162 class ProfileSummaryPrinterPass
    163     : public PassInfoMixin<ProfileSummaryPrinterPass> {
    164   raw_ostream &OS;
    165 
    166 public:
    167   explicit ProfileSummaryPrinterPass(raw_ostream &OS) : OS(OS) {}
    168   PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
    169 };
    170 
    171 } // end namespace llvm
    172 
    173 #endif
    174