//===- llvm/Analysis/ProfileSummaryInfo.h - profile summary ---*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains a pass that provides access to profile summary
// information.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_ANALYSIS_PROFILESUMMARYINFO_H
#define LLVM_ANALYSIS_PROFILESUMMARYINFO_H

#include "llvm/ADT/DenseMap.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/ProfileSummary.h"
#include "llvm/Pass.h"
#include <memory>

namespace llvm {
class BasicBlock;
class BlockFrequencyInfo;
class CallBase;
class Function;

/// Analysis providing profile information.
///
/// This is an immutable analysis pass that provides ability to query global
/// (program-level) profile information. The main APIs are isHotCount and
/// isColdCount that tells whether a given profile count is considered hot/cold
/// based on the profile summary. This also provides convenience methods to
/// check whether a function is hot or cold.

// FIXME: Provide convenience methods to determine hotness/coldness of other IR
// units. This would require making this depend on BFI.
class ProfileSummaryInfo {
private:
  const Module *M;
  std::unique_ptr<ProfileSummary> Summary;
  void computeThresholds();
  // Count thresholds to answer isHotCount and isColdCount queries.
  Optional<uint64_t> HotCountThreshold, ColdCountThreshold;
  // True if the working set size of the code is considered huge,
  // because the number of profile counts required to reach the hot
  // percentile is above a huge threshold.
  Optional<bool> HasHugeWorkingSetSize;
  // True if the working set size of the code is considered large,
  // because the number of profile counts required to reach the hot
  // percentile is above a large threshold.
  Optional<bool> HasLargeWorkingSetSize;
  // Compute the threshold for a given cutoff.
  Optional<uint64_t> computeThreshold(int PercentileCutoff) const;
  // The map that caches the threshold values. The keys are the percentile
  // cutoff values and the values are the corresponding threshold values.
  mutable DenseMap<int, uint64_t> ThresholdCache;

public:
  ProfileSummaryInfo(const Module &M) : M(&M) { refresh(); }
  ProfileSummaryInfo(std::unique_ptr<ProfileSummary> PSI)
      : M(nullptr), Summary(std::move(PSI)) {}

  ProfileSummaryInfo(ProfileSummaryInfo &&Arg) = default;

  /// If no summary is present, attempt to refresh.
  void refresh();

  /// Returns true if profile summary is available.
  bool hasProfileSummary() const { return Summary != nullptr; }

  /// Returns true if module \c M has sample profile.
  bool hasSampleProfile() const {
    return hasProfileSummary() &&
           Summary->getKind() == ProfileSummary::PSK_Sample;
  }

  /// Returns true if module \c M has instrumentation profile.
  bool hasInstrumentationProfile() const {
    return hasProfileSummary() &&
           Summary->getKind() == ProfileSummary::PSK_Instr;
  }

  /// Returns true if module \c M has context sensitive instrumentation profile.
  bool hasCSInstrumentationProfile() const {
    return hasProfileSummary() &&
           Summary->getKind() == ProfileSummary::PSK_CSInstr;
  }

  /// Handle the invalidation of this information.
  ///
  /// When used as a result of \c ProfileSummaryAnalysis this method will be
  /// called when the module this was computed for changes. Since profile
  /// summary is immutable after it is annotated on the module, we return false
  /// here.
  bool invalidate(Module &, const PreservedAnalyses &,
                  ModuleAnalysisManager::Invalidator &) {
    return false;
  }

  /// Returns the profile count for \p CallInst.
  Optional<uint64_t> getProfileCount(const CallBase &CallInst,
                                     BlockFrequencyInfo *BFI,
                                     bool AllowSynthetic = false) const;
  /// Returns true if module \c M has partial-profile sample profile.
  bool hasPartialSampleProfile() const;
  /// Returns true if the working set size of the code is considered huge.
  bool hasHugeWorkingSetSize() const;
  /// Returns true if the working set size of the code is considered large.
  bool hasLargeWorkingSetSize() const;
  /// Returns true if \p F has hot function entry.
  bool isFunctionEntryHot(const Function *F) const;
  /// Returns true if \p F contains hot code.
  bool isFunctionHotInCallGraph(const Function *F,
                                BlockFrequencyInfo &BFI) const;
  /// Returns true if \p F has cold function entry.
  bool isFunctionEntryCold(const Function *F) const;
  /// Returns true if \p F contains only cold code.
  bool isFunctionColdInCallGraph(const Function *F,
                                 BlockFrequencyInfo &BFI) const;
  /// Returns true if the hotness of \p F is unknown.
  bool isFunctionHotnessUnknown(const Function &F) const;
  /// Returns true if \p F contains hot code with regard to a given hot
  /// percentile cutoff value.
  bool isFunctionHotInCallGraphNthPercentile(int PercentileCutoff,
                                             const Function *F,
                                             BlockFrequencyInfo &BFI) const;
  /// Returns true if \p F contains cold code with regard to a given cold
  /// percentile cutoff value.
  bool isFunctionColdInCallGraphNthPercentile(int PercentileCutoff,
                                              const Function *F,
                                              BlockFrequencyInfo &BFI) const;
  /// Returns true if count \p C is considered hot.
  bool isHotCount(uint64_t C) const;
  /// Returns true if count \p C is considered cold.
  bool isColdCount(uint64_t C) const;
  /// Returns true if count \p C is considered hot with regard to a given
  /// hot percentile cutoff value.
  bool isHotCountNthPercentile(int PercentileCutoff, uint64_t C) const;
  /// Returns true if count \p C is considered cold with regard to a given
  /// cold percentile cutoff value.
  bool isColdCountNthPercentile(int PercentileCutoff, uint64_t C) const;
  /// Returns true if BasicBlock \p BB is considered hot.
  bool isHotBlock(const BasicBlock *BB, BlockFrequencyInfo *BFI) const;
  /// Returns true if BasicBlock \p BB is considered cold.
  bool isColdBlock(const BasicBlock *BB, BlockFrequencyInfo *BFI) const;
  /// Returns true if BasicBlock \p BB is considered hot with regard to a given
  /// hot percentile cutoff value.
  bool isHotBlockNthPercentile(int PercentileCutoff, const BasicBlock *BB,
                               BlockFrequencyInfo *BFI) const;
  /// Returns true if BasicBlock \p BB is considered cold with regard to a given
  /// cold percentile cutoff value.
  bool isColdBlockNthPercentile(int PercentileCutoff, const BasicBlock *BB,
                                BlockFrequencyInfo *BFI) const;
  /// Returns true if the call site \p CB is considered hot.
  bool isHotCallSite(const CallBase &CB, BlockFrequencyInfo *BFI) const;
  /// Returns true if call site \p CB is considered cold.
  bool isColdCallSite(const CallBase &CB, BlockFrequencyInfo *BFI) const;
  /// Returns HotCountThreshold if set. Recompute HotCountThreshold
  /// if not set.
  uint64_t getOrCompHotCountThreshold() const;
  /// Returns ColdCountThreshold if set. Recompute HotCountThreshold
  /// if not set.
  uint64_t getOrCompColdCountThreshold() const;
  /// Returns HotCountThreshold if set.
  uint64_t getHotCountThreshold() const {
    return HotCountThreshold ? HotCountThreshold.getValue() : 0;
  }
  /// Returns ColdCountThreshold if set.
  uint64_t getColdCountThreshold() const {
    return ColdCountThreshold ? ColdCountThreshold.getValue() : 0;
  }

 private:
   template <bool isHot>
   bool isFunctionHotOrColdInCallGraphNthPercentile(
       int PercentileCutoff, const Function *F, BlockFrequencyInfo &BFI) const;
   template <bool isHot>
   bool isHotOrColdCountNthPercentile(int PercentileCutoff, uint64_t C) const;
   template <bool isHot>
   bool isHotOrColdBlockNthPercentile(int PercentileCutoff,
                                      const BasicBlock *BB,
                                      BlockFrequencyInfo *BFI) const;
};

/// An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
class ProfileSummaryInfoWrapperPass : public ImmutablePass {
  std::unique_ptr<ProfileSummaryInfo> PSI;

public:
  static char ID;
  ProfileSummaryInfoWrapperPass();

  ProfileSummaryInfo &getPSI() { return *PSI; }
  const ProfileSummaryInfo &getPSI() const { return *PSI; }

  bool doInitialization(Module &M) override;
  bool doFinalization(Module &M) override;
  void getAnalysisUsage(AnalysisUsage &AU) const override {
    AU.setPreservesAll();
  }
};

/// An analysis pass based on the new PM to deliver ProfileSummaryInfo.
class ProfileSummaryAnalysis
    : public AnalysisInfoMixin<ProfileSummaryAnalysis> {
public:
  typedef ProfileSummaryInfo Result;

  Result run(Module &M, ModuleAnalysisManager &);

private:
  friend AnalysisInfoMixin<ProfileSummaryAnalysis>;
  static AnalysisKey Key;
};

/// Printer pass that uses \c ProfileSummaryAnalysis.
class ProfileSummaryPrinterPass
    : public PassInfoMixin<ProfileSummaryPrinterPass> {
  raw_ostream &OS;

public:
  explicit ProfileSummaryPrinterPass(raw_ostream &OS) : OS(OS) {}
  PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
};

} // end namespace llvm

#endif
