//===- SampleProfile.cpp - Incorporate sample profiles into the IR --------===//
//
// 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 implements the SampleProfileLoader transformation. This pass
// reads a profile file generated by a sampling profiler (e.g. Linux Perf -
// http://perf.wiki.kernel.org/) and generates IR metadata to reflect the
// profile information in the given profile.
//
// This pass generates branch weight annotations on the IR:
//
// - prof: Represents branch weights. This annotation is added to branches
//      to indicate the weights of each edge coming out of the branch.
//      The weight of each edge is the weight of the target block for
//      that edge. The weight of a block B is computed as the maximum
//      number of samples found in B.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/IPO/SampleProfile.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/PriorityQueue.h"
#include "llvm/ADT/SCCIterator.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Analysis/AssumptionCache.h"
#include "llvm/Analysis/BlockFrequencyInfoImpl.h"
#include "llvm/Analysis/InlineAdvisor.h"
#include "llvm/Analysis/InlineCost.h"
#include "llvm/Analysis/LazyCallGraph.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
#include "llvm/Analysis/ReplayInlineAdvisor.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/ProfDataUtils.h"
#include "llvm/IR/PseudoProbe.h"
#include "llvm/IR/ValueSymbolTable.h"
#include "llvm/ProfileData/InstrProf.h"
#include "llvm/ProfileData/SampleProf.h"
#include "llvm/ProfileData/SampleProfReader.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/IPO/ProfiledCallGraph.h"
#include "llvm/Transforms/IPO/SampleContextTracker.h"
#include "llvm/Transforms/IPO/SampleProfileMatcher.h"
#include "llvm/Transforms/IPO/SampleProfileProbe.h"
#include "llvm/Transforms/Utils/CallPromotionUtils.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Transforms/Utils/Instrumentation.h"
#include "llvm/Transforms/Utils/MisExpect.h"
#include "llvm/Transforms/Utils/SampleProfileLoaderBaseImpl.h"
#include "llvm/Transforms/Utils/SampleProfileLoaderBaseUtil.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <functional>
#include <limits>
#include <memory>
#include <queue>
#include <string>
#include <system_error>
#include <utility>
#include <vector>

using namespace llvm;
using namespace sampleprof;
using namespace llvm::sampleprofutil;
using ProfileCount = Function::ProfileCount;
#define DEBUG_TYPE "sample-profile"
#define CSINLINE_DEBUG DEBUG_TYPE "-inline"

STATISTIC(NumCSInlined,
          "Number of functions inlined with context sensitive profile");
STATISTIC(NumCSNotInlined,
          "Number of functions not inlined with context sensitive profile");
STATISTIC(NumMismatchedProfile,
          "Number of functions with CFG mismatched profile");
STATISTIC(NumMatchedProfile, "Number of functions with CFG matched profile");
STATISTIC(NumDuplicatedInlinesite,
          "Number of inlined callsites with a partial distribution factor");

STATISTIC(NumCSInlinedHitMinLimit,
          "Number of functions with FDO inline stopped due to min size limit");
STATISTIC(NumCSInlinedHitMaxLimit,
          "Number of functions with FDO inline stopped due to max size limit");
STATISTIC(
    NumCSInlinedHitGrowthLimit,
    "Number of functions with FDO inline stopped due to growth size limit");

namespace llvm {

// Command line option to specify the file to read samples from. This is
// mainly used for debugging.
static cl::opt<std::string> SampleProfileFile(
    "sample-profile-file", cl::init(""), cl::value_desc("filename"),
    cl::desc("Profile file loaded by -sample-profile"), cl::Hidden);

// The named file contains a set of transformations that may have been applied
// to the symbol names between the program from which the sample data was
// collected and the current program's symbols.
static cl::opt<std::string> SampleProfileRemappingFile(
    "sample-profile-remapping-file", cl::init(""), cl::value_desc("filename"),
    cl::desc("Profile remapping file loaded by -sample-profile"), cl::Hidden);

cl::opt<bool> SalvageStaleProfile(
    "salvage-stale-profile", cl::Hidden, cl::init(false),
    cl::desc("Salvage stale profile by fuzzy matching and use the remapped "
             "location for sample profile query."));
cl::opt<bool>
    SalvageUnusedProfile("salvage-unused-profile", cl::Hidden, cl::init(false),
                         cl::desc("Salvage unused profile by matching with new "
                                  "functions on call graph."));

cl::opt<bool> ReportProfileStaleness(
    "report-profile-staleness", cl::Hidden, cl::init(false),
    cl::desc("Compute and report stale profile statistical metrics."));

cl::opt<bool> PersistProfileStaleness(
    "persist-profile-staleness", cl::Hidden, cl::init(false),
    cl::desc("Compute stale profile statistical metrics and write it into the "
             "native object file(.llvm_stats section)."));

static cl::opt<bool> ProfileSampleAccurate(
    "profile-sample-accurate", cl::Hidden, cl::init(false),
    cl::desc("If the sample profile is accurate, we will mark all un-sampled "
             "callsite and function as having 0 samples. Otherwise, treat "
             "un-sampled callsites and functions conservatively as unknown. "));

static cl::opt<bool> ProfileSampleBlockAccurate(
    "profile-sample-block-accurate", cl::Hidden, cl::init(false),
    cl::desc("If the sample profile is accurate, we will mark all un-sampled "
             "branches and calls as having 0 samples. Otherwise, treat "
             "them conservatively as unknown. "));

static cl::opt<bool> ProfileAccurateForSymsInList(
    "profile-accurate-for-symsinlist", cl::Hidden, cl::init(true),
    cl::desc("For symbols in profile symbol list, regard their profiles to "
             "be accurate. It may be overridden by profile-sample-accurate. "));

static cl::opt<bool> ProfileMergeInlinee(
    "sample-profile-merge-inlinee", cl::Hidden, cl::init(true),
    cl::desc("Merge past inlinee's profile to outline version if sample "
             "profile loader decided not to inline a call site. It will "
             "only be enabled when top-down order of profile loading is "
             "enabled. "));

static cl::opt<bool> ProfileTopDownLoad(
    "sample-profile-top-down-load", cl::Hidden, cl::init(true),
    cl::desc("Do profile annotation and inlining for functions in top-down "
             "order of call graph during sample profile loading. It only "
             "works for new pass manager. "));

static cl::opt<bool>
    UseProfiledCallGraph("use-profiled-call-graph", cl::init(true), cl::Hidden,
                         cl::desc("Process functions in a top-down order "
                                  "defined by the profiled call graph when "
                                  "-sample-profile-top-down-load is on."));

static cl::opt<bool> ProfileSizeInline(
    "sample-profile-inline-size", cl::Hidden, cl::init(false),
    cl::desc("Inline cold call sites in profile loader if it's beneficial "
             "for code size."));

// Since profiles are consumed by many passes, turning on this option has
// side effects. For instance, pre-link SCC inliner would see merged profiles
// and inline the hot functions (that are skipped in this pass).
static cl::opt<bool> DisableSampleLoaderInlining(
    "disable-sample-loader-inlining", cl::Hidden, cl::init(false),
    cl::desc(
        "If true, artificially skip inline transformation in sample-loader "
        "pass, and merge (or scale) profiles (as configured by "
        "--sample-profile-merge-inlinee)."));

cl::opt<bool>
    SortProfiledSCC("sort-profiled-scc-member", cl::init(true), cl::Hidden,
                    cl::desc("Sort profiled recursion by edge weights."));

cl::opt<int> ProfileInlineGrowthLimit(
    "sample-profile-inline-growth-limit", cl::Hidden, cl::init(12),
    cl::desc("The size growth ratio limit for proirity-based sample profile "
             "loader inlining."));

cl::opt<int> ProfileInlineLimitMin(
    "sample-profile-inline-limit-min", cl::Hidden, cl::init(100),
    cl::desc("The lower bound of size growth limit for "
             "proirity-based sample profile loader inlining."));

cl::opt<int> ProfileInlineLimitMax(
    "sample-profile-inline-limit-max", cl::Hidden, cl::init(10000),
    cl::desc("The upper bound of size growth limit for "
             "proirity-based sample profile loader inlining."));

cl::opt<int> SampleHotCallSiteThreshold(
    "sample-profile-hot-inline-threshold", cl::Hidden, cl::init(3000),
    cl::desc("Hot callsite threshold for proirity-based sample profile loader "
             "inlining."));

cl::opt<int> SampleColdCallSiteThreshold(
    "sample-profile-cold-inline-threshold", cl::Hidden, cl::init(45),
    cl::desc("Threshold for inlining cold callsites"));
} // namespace llvm

static cl::opt<unsigned> ProfileICPRelativeHotness(
    "sample-profile-icp-relative-hotness", cl::Hidden, cl::init(25),
    cl::desc(
        "Relative hotness percentage threshold for indirect "
        "call promotion in proirity-based sample profile loader inlining."));

static cl::opt<unsigned> ProfileICPRelativeHotnessSkip(
    "sample-profile-icp-relative-hotness-skip", cl::Hidden, cl::init(1),
    cl::desc(
        "Skip relative hotness check for ICP up to given number of targets."));

static cl::opt<unsigned> HotFuncCutoffForStalenessError(
    "hot-func-cutoff-for-staleness-error", cl::Hidden, cl::init(800000),
    cl::desc("A function is considered hot for staleness error check if its "
             "total sample count is above the specified percentile"));

static cl::opt<unsigned> MinfuncsForStalenessError(
    "min-functions-for-staleness-error", cl::Hidden, cl::init(50),
    cl::desc("Skip the check if the number of hot functions is smaller than "
             "the specified number."));

static cl::opt<unsigned> PrecentMismatchForStalenessError(
    "precent-mismatch-for-staleness-error", cl::Hidden, cl::init(80),
    cl::desc("Reject the profile if the mismatch percent is higher than the "
             "given number."));

static cl::opt<bool> CallsitePrioritizedInline(
    "sample-profile-prioritized-inline", cl::Hidden,
    cl::desc("Use call site prioritized inlining for sample profile loader. "
             "Currently only CSSPGO is supported."));

static cl::opt<bool> UsePreInlinerDecision(
    "sample-profile-use-preinliner", cl::Hidden,
    cl::desc("Use the preinliner decisions stored in profile context."));

static cl::opt<bool> AllowRecursiveInline(
    "sample-profile-recursive-inline", cl::Hidden,
    cl::desc("Allow sample loader inliner to inline recursive calls."));

static cl::opt<bool> RemoveProbeAfterProfileAnnotation(
    "sample-profile-remove-probe", cl::Hidden, cl::init(false),
    cl::desc("Remove pseudo-probe after sample profile annotation."));

static cl::opt<std::string> ProfileInlineReplayFile(
    "sample-profile-inline-replay", cl::init(""), cl::value_desc("filename"),
    cl::desc(
        "Optimization remarks file containing inline remarks to be replayed "
        "by inlining from sample profile loader."),
    cl::Hidden);

static cl::opt<ReplayInlinerSettings::Scope> ProfileInlineReplayScope(
    "sample-profile-inline-replay-scope",
    cl::init(ReplayInlinerSettings::Scope::Function),
    cl::values(clEnumValN(ReplayInlinerSettings::Scope::Function, "Function",
                          "Replay on functions that have remarks associated "
                          "with them (default)"),
               clEnumValN(ReplayInlinerSettings::Scope::Module, "Module",
                          "Replay on the entire module")),
    cl::desc("Whether inline replay should be applied to the entire "
             "Module or just the Functions (default) that are present as "
             "callers in remarks during sample profile inlining."),
    cl::Hidden);

static cl::opt<ReplayInlinerSettings::Fallback> ProfileInlineReplayFallback(
    "sample-profile-inline-replay-fallback",
    cl::init(ReplayInlinerSettings::Fallback::Original),
    cl::values(
        clEnumValN(
            ReplayInlinerSettings::Fallback::Original, "Original",
            "All decisions not in replay send to original advisor (default)"),
        clEnumValN(ReplayInlinerSettings::Fallback::AlwaysInline,
                   "AlwaysInline", "All decisions not in replay are inlined"),
        clEnumValN(ReplayInlinerSettings::Fallback::NeverInline, "NeverInline",
                   "All decisions not in replay are not inlined")),
    cl::desc("How sample profile inline replay treats sites that don't come "
             "from the replay. Original: defers to original advisor, "
             "AlwaysInline: inline all sites not in replay, NeverInline: "
             "inline no sites not in replay"),
    cl::Hidden);

static cl::opt<CallSiteFormat::Format> ProfileInlineReplayFormat(
    "sample-profile-inline-replay-format",
    cl::init(CallSiteFormat::Format::LineColumnDiscriminator),
    cl::values(
        clEnumValN(CallSiteFormat::Format::Line, "Line", "<Line Number>"),
        clEnumValN(CallSiteFormat::Format::LineColumn, "LineColumn",
                   "<Line Number>:<Column Number>"),
        clEnumValN(CallSiteFormat::Format::LineDiscriminator,
                   "LineDiscriminator", "<Line Number>.<Discriminator>"),
        clEnumValN(CallSiteFormat::Format::LineColumnDiscriminator,
                   "LineColumnDiscriminator",
                   "<Line Number>:<Column Number>.<Discriminator> (default)")),
    cl::desc("How sample profile inline replay file is formatted"), cl::Hidden);

static cl::opt<unsigned>
    MaxNumPromotions("sample-profile-icp-max-prom", cl::init(3), cl::Hidden,
                     cl::desc("Max number of promotions for a single indirect "
                              "call callsite in sample profile loader"));

static cl::opt<bool> OverwriteExistingWeights(
    "overwrite-existing-weights", cl::Hidden, cl::init(false),
    cl::desc("Ignore existing branch weights on IR and always overwrite."));

static cl::opt<bool> AnnotateSampleProfileInlinePhase(
    "annotate-sample-profile-inline-phase", cl::Hidden, cl::init(false),
    cl::desc("Annotate LTO phase (prelink / postlink), or main (no LTO) for "
             "sample-profile inline pass name."));

namespace llvm {
extern cl::opt<bool> EnableExtTspBlockPlacement;
}

namespace {

using BlockWeightMap = DenseMap<const BasicBlock *, uint64_t>;
using EquivalenceClassMap = DenseMap<const BasicBlock *, const BasicBlock *>;
using Edge = std::pair<const BasicBlock *, const BasicBlock *>;
using EdgeWeightMap = DenseMap<Edge, uint64_t>;
using BlockEdgeMap =
    DenseMap<const BasicBlock *, SmallVector<const BasicBlock *, 8>>;

class GUIDToFuncNameMapper {
public:
  GUIDToFuncNameMapper(Module &M, SampleProfileReader &Reader,
                       DenseMap<uint64_t, StringRef> &GUIDToFuncNameMap)
      : CurrentReader(Reader), CurrentModule(M),
        CurrentGUIDToFuncNameMap(GUIDToFuncNameMap) {
    if (!CurrentReader.useMD5())
      return;

    for (const auto &F : CurrentModule) {
      StringRef OrigName = F.getName();
      CurrentGUIDToFuncNameMap.insert(
          {Function::getGUIDAssumingExternalLinkage(OrigName), OrigName});

      // Local to global var promotion used by optimization like thinlto
      // will rename the var and add suffix like ".llvm.xxx" to the
      // original local name. In sample profile, the suffixes of function
      // names are all stripped. Since it is possible that the mapper is
      // built in post-thin-link phase and var promotion has been done,
      // we need to add the substring of function name without the suffix
      // into the GUIDToFuncNameMap.
      StringRef CanonName = FunctionSamples::getCanonicalFnName(F);
      if (CanonName != OrigName)
        CurrentGUIDToFuncNameMap.insert(
            {Function::getGUIDAssumingExternalLinkage(CanonName), CanonName});
    }

    // Update GUIDToFuncNameMap for each function including inlinees.
    SetGUIDToFuncNameMapForAll(&CurrentGUIDToFuncNameMap);
  }

  ~GUIDToFuncNameMapper() {
    if (!CurrentReader.useMD5())
      return;

    CurrentGUIDToFuncNameMap.clear();

    // Reset GUIDToFuncNameMap for of each function as they're no
    // longer valid at this point.
    SetGUIDToFuncNameMapForAll(nullptr);
  }

private:
  void SetGUIDToFuncNameMapForAll(DenseMap<uint64_t, StringRef> *Map) {
    std::queue<FunctionSamples *> FSToUpdate;
    for (auto &IFS : CurrentReader.getProfiles()) {
      FSToUpdate.push(&IFS.second);
    }

    while (!FSToUpdate.empty()) {
      FunctionSamples *FS = FSToUpdate.front();
      FSToUpdate.pop();
      FS->GUIDToFuncNameMap = Map;
      for (const auto &ICS : FS->getCallsiteSamples()) {
        const FunctionSamplesMap &FSMap = ICS.second;
        for (const auto &IFS : FSMap) {
          FunctionSamples &FS = const_cast<FunctionSamples &>(IFS.second);
          FSToUpdate.push(&FS);
        }
      }
    }
  }

  SampleProfileReader &CurrentReader;
  Module &CurrentModule;
  DenseMap<uint64_t, StringRef> &CurrentGUIDToFuncNameMap;
};

// Inline candidate used by iterative callsite prioritized inliner
struct InlineCandidate {
  CallBase *CallInstr;
  const FunctionSamples *CalleeSamples;
  // Prorated callsite count, which will be used to guide inlining. For example,
  // if a callsite is duplicated in LTO prelink, then in LTO postlink the two
  // copies will get their own distribution factors and their prorated counts
  // will be used to decide if they should be inlined independently.
  uint64_t CallsiteCount;
  // Call site distribution factor to prorate the profile samples for a
  // duplicated callsite. Default value is 1.0.
  float CallsiteDistribution;
};

// Inline candidate comparer using call site weight
struct CandidateComparer {
  bool operator()(const InlineCandidate &LHS, const InlineCandidate &RHS) {
    if (LHS.CallsiteCount != RHS.CallsiteCount)
      return LHS.CallsiteCount < RHS.CallsiteCount;

    const FunctionSamples *LCS = LHS.CalleeSamples;
    const FunctionSamples *RCS = RHS.CalleeSamples;
    // In inline replay mode, CalleeSamples may be null and the order doesn't
    // matter.
    if (!LCS || !RCS)
      return LCS;

    // Tie breaker using number of samples try to favor smaller functions first
    if (LCS->getBodySamples().size() != RCS->getBodySamples().size())
      return LCS->getBodySamples().size() > RCS->getBodySamples().size();

    // Tie breaker using GUID so we have stable/deterministic inlining order
    return LCS->getGUID() < RCS->getGUID();
  }
};

using CandidateQueue =
    PriorityQueue<InlineCandidate, std::vector<InlineCandidate>,
                  CandidateComparer>;

/// Sample profile pass.
///
/// This pass reads profile data from the file specified by
/// -sample-profile-file and annotates every affected function with the
/// profile information found in that file.
class SampleProfileLoader final : public SampleProfileLoaderBaseImpl<Function> {
public:
  SampleProfileLoader(
      StringRef Name, StringRef RemapName, ThinOrFullLTOPhase LTOPhase,
      IntrusiveRefCntPtr<vfs::FileSystem> FS,
      std::function<AssumptionCache &(Function &)> GetAssumptionCache,
      std::function<TargetTransformInfo &(Function &)> GetTargetTransformInfo,
      std::function<const TargetLibraryInfo &(Function &)> GetTLI,
      LazyCallGraph &CG, bool DisableSampleProfileInlining,
      bool UseFlattenedProfile)
      : SampleProfileLoaderBaseImpl(std::string(Name), std::string(RemapName),
                                    std::move(FS)),
        GetAC(std::move(GetAssumptionCache)),
        GetTTI(std::move(GetTargetTransformInfo)), GetTLI(std::move(GetTLI)),
        CG(CG), LTOPhase(LTOPhase),
        AnnotatedPassName(AnnotateSampleProfileInlinePhase
                              ? llvm::AnnotateInlinePassName(InlineContext{
                                    LTOPhase, InlinePass::SampleProfileInliner})
                              : CSINLINE_DEBUG),
        DisableSampleProfileInlining(DisableSampleProfileInlining),
        UseFlattenedProfile(UseFlattenedProfile) {}

  bool doInitialization(Module &M, FunctionAnalysisManager *FAM = nullptr);
  bool runOnModule(Module &M, ModuleAnalysisManager &AM,
                   ProfileSummaryInfo *_PSI);

protected:
  bool runOnFunction(Function &F, ModuleAnalysisManager &AM);
  bool emitAnnotations(Function &F);
  ErrorOr<uint64_t> getInstWeight(const Instruction &I) override;
  const FunctionSamples *findCalleeFunctionSamples(const CallBase &I) const;
  const FunctionSamples *
  findFunctionSamples(const Instruction &I) const override;
  std::vector<const FunctionSamples *>
  findIndirectCallFunctionSamples(const Instruction &I, uint64_t &Sum) const;
  void findExternalInlineCandidate(CallBase *CB, const FunctionSamples *Samples,
                                   DenseSet<GlobalValue::GUID> &InlinedGUIDs,
                                   uint64_t Threshold);
  // Attempt to promote indirect call and also inline the promoted call
  bool tryPromoteAndInlineCandidate(
      Function &F, InlineCandidate &Candidate, uint64_t SumOrigin,
      uint64_t &Sum, SmallVector<CallBase *, 8> *InlinedCallSites = nullptr);

  bool inlineHotFunctions(Function &F,
                          DenseSet<GlobalValue::GUID> &InlinedGUIDs);
  std::optional<InlineCost> getExternalInlineAdvisorCost(CallBase &CB);
  bool getExternalInlineAdvisorShouldInline(CallBase &CB);
  InlineCost shouldInlineCandidate(InlineCandidate &Candidate);
  bool getInlineCandidate(InlineCandidate *NewCandidate, CallBase *CB);
  bool
  tryInlineCandidate(InlineCandidate &Candidate,
                     SmallVector<CallBase *, 8> *InlinedCallSites = nullptr);
  bool
  inlineHotFunctionsWithPriority(Function &F,
                                 DenseSet<GlobalValue::GUID> &InlinedGUIDs);
  // Inline cold/small functions in addition to hot ones
  bool shouldInlineColdCallee(CallBase &CallInst);
  void emitOptimizationRemarksForInlineCandidates(
      const SmallVectorImpl<CallBase *> &Candidates, const Function &F,
      bool Hot);
  void promoteMergeNotInlinedContextSamples(
      MapVector<CallBase *, const FunctionSamples *> NonInlinedCallSites,
      const Function &F);
  std::vector<Function *> buildFunctionOrder(Module &M, LazyCallGraph &CG);
  std::unique_ptr<ProfiledCallGraph> buildProfiledCallGraph(Module &M);
  void generateMDProfMetadata(Function &F);
  bool rejectHighStalenessProfile(Module &M, ProfileSummaryInfo *PSI,
                                  const SampleProfileMap &Profiles);
  void removePseudoProbeInstsDiscriminator(Module &M);

  /// Map from function name to Function *. Used to find the function from
  /// the function name. If the function name contains suffix, additional
  /// entry is added to map from the stripped name to the function if there
  /// is one-to-one mapping.
  HashKeyMap<std::unordered_map, FunctionId, Function *> SymbolMap;

  /// Map from function name to profile name generated by call-graph based
  /// profile fuzzy matching(--salvage-unused-profile).
  HashKeyMap<std::unordered_map, FunctionId, FunctionId> FuncNameToProfNameMap;

  std::function<AssumptionCache &(Function &)> GetAC;
  std::function<TargetTransformInfo &(Function &)> GetTTI;
  std::function<const TargetLibraryInfo &(Function &)> GetTLI;
  LazyCallGraph &CG;

  /// Profile tracker for different context.
  std::unique_ptr<SampleContextTracker> ContextTracker;

  /// Flag indicating which LTO/ThinLTO phase the pass is invoked in.
  ///
  /// We need to know the LTO phase because for example in ThinLTOPrelink
  /// phase, in annotation, we should not promote indirect calls. Instead,
  /// we will mark GUIDs that needs to be annotated to the function.
  const ThinOrFullLTOPhase LTOPhase;
  const std::string AnnotatedPassName;

  /// Profle Symbol list tells whether a function name appears in the binary
  /// used to generate the current profile.
  std::shared_ptr<ProfileSymbolList> PSL;

  // Information recorded when we declined to inline a call site
  // because we have determined it is too cold is accumulated for
  // each callee function. Initially this is just the entry count.
  struct NotInlinedProfileInfo {
    uint64_t entryCount;
  };
  DenseMap<Function *, NotInlinedProfileInfo> notInlinedCallInfo;

  // GUIDToFuncNameMap saves the mapping from GUID to the symbol name, for
  // all the function symbols defined or declared in current module.
  DenseMap<uint64_t, StringRef> GUIDToFuncNameMap;

  // All the Names used in FunctionSamples including outline function
  // names, inline instance names and call target names.
  StringSet<> NamesInProfile;
  // MD5 version of NamesInProfile. Either NamesInProfile or GUIDsInProfile is
  // populated, depends on whether the profile uses MD5. Because the name table
  // generally contains several magnitude more entries than the number of
  // functions, we do not want to convert all names from one form to another.
  llvm::DenseSet<uint64_t> GUIDsInProfile;

  // For symbol in profile symbol list, whether to regard their profiles
  // to be accurate. It is mainly decided by existance of profile symbol
  // list and -profile-accurate-for-symsinlist flag, but it can be
  // overriden by -profile-sample-accurate or profile-sample-accurate
  // attribute.
  bool ProfAccForSymsInList;

  bool DisableSampleProfileInlining;

  bool UseFlattenedProfile;

  // External inline advisor used to replay inline decision from remarks.
  std::unique_ptr<InlineAdvisor> ExternalInlineAdvisor;

  // A helper to implement the sample profile matching algorithm.
  std::unique_ptr<SampleProfileMatcher> MatchingManager;

private:
  const char *getAnnotatedRemarkPassName() const {
    return AnnotatedPassName.c_str();
  }
};
} // end anonymous namespace

namespace llvm {
template <>
inline bool SampleProfileInference<Function>::isExit(const BasicBlock *BB) {
  return succ_empty(BB);
}

template <>
inline void SampleProfileInference<Function>::findUnlikelyJumps(
    const std::vector<const BasicBlockT *> &BasicBlocks,
    BlockEdgeMap &Successors, FlowFunction &Func) {
  for (auto &Jump : Func.Jumps) {
    const auto *BB = BasicBlocks[Jump.Source];
    const auto *Succ = BasicBlocks[Jump.Target];
    const Instruction *TI = BB->getTerminator();
    // Check if a block ends with InvokeInst and mark non-taken branch unlikely.
    // In that case block Succ should be a landing pad
    const auto &Succs = Successors[BB];
    if (Succs.size() == 2 && Succs.back() == Succ) {
      if (isa<InvokeInst>(TI)) {
        Jump.IsUnlikely = true;
      }
    }
    const Instruction *SuccTI = Succ->getTerminator();
    // Check if the target block contains UnreachableInst and mark it unlikely
    if (SuccTI->getNumSuccessors() == 0) {
      if (isa<UnreachableInst>(SuccTI)) {
        Jump.IsUnlikely = true;
      }
    }
  }
}

template <>
void SampleProfileLoaderBaseImpl<Function>::computeDominanceAndLoopInfo(
    Function &F) {
  DT.reset(new DominatorTree);
  DT->recalculate(F);

  PDT.reset(new PostDominatorTree(F));

  LI.reset(new LoopInfo);
  LI->analyze(*DT);
}
} // namespace llvm

ErrorOr<uint64_t> SampleProfileLoader::getInstWeight(const Instruction &Inst) {
  if (FunctionSamples::ProfileIsProbeBased)
    return getProbeWeight(Inst);

  const DebugLoc &DLoc = Inst.getDebugLoc();
  if (!DLoc)
    return std::error_code();

  // Ignore all intrinsics, phinodes and branch instructions.
  // Branch and phinodes instruction usually contains debug info from sources
  // outside of the residing basic block, thus we ignore them during annotation.
  if (isa<BranchInst>(Inst) || isa<IntrinsicInst>(Inst) || isa<PHINode>(Inst))
    return std::error_code();

  // For non-CS profile, if a direct call/invoke instruction is inlined in
  // profile (findCalleeFunctionSamples returns non-empty result), but not
  // inlined here, it means that the inlined callsite has no sample, thus the
  // call instruction should have 0 count.
  // For CS profile, the callsite count of previously inlined callees is
  // populated with the entry count of the callees.
  if (!FunctionSamples::ProfileIsCS)
    if (const auto *CB = dyn_cast<CallBase>(&Inst))
      if (!CB->isIndirectCall() && findCalleeFunctionSamples(*CB))
        return 0;

  return getInstWeightImpl(Inst);
}

/// Get the FunctionSamples for a call instruction.
///
/// The FunctionSamples of a call/invoke instruction \p Inst is the inlined
/// instance in which that call instruction is calling to. It contains
/// all samples that resides in the inlined instance. We first find the
/// inlined instance in which the call instruction is from, then we
/// traverse its children to find the callsite with the matching
/// location.
///
/// \param Inst Call/Invoke instruction to query.
///
/// \returns The FunctionSamples pointer to the inlined instance.
const FunctionSamples *
SampleProfileLoader::findCalleeFunctionSamples(const CallBase &Inst) const {
  const DILocation *DIL = Inst.getDebugLoc();
  if (!DIL) {
    return nullptr;
  }

  StringRef CalleeName;
  if (Function *Callee = Inst.getCalledFunction())
    CalleeName = Callee->getName();

  if (FunctionSamples::ProfileIsCS)
    return ContextTracker->getCalleeContextSamplesFor(Inst, CalleeName);

  const FunctionSamples *FS = findFunctionSamples(Inst);
  if (FS == nullptr)
    return nullptr;

  return FS->findFunctionSamplesAt(FunctionSamples::getCallSiteIdentifier(DIL),
                                   CalleeName, Reader->getRemapper(),
                                   &FuncNameToProfNameMap);
}

/// Returns a vector of FunctionSamples that are the indirect call targets
/// of \p Inst. The vector is sorted by the total number of samples. Stores
/// the total call count of the indirect call in \p Sum.
std::vector<const FunctionSamples *>
SampleProfileLoader::findIndirectCallFunctionSamples(
    const Instruction &Inst, uint64_t &Sum) const {
  const DILocation *DIL = Inst.getDebugLoc();
  std::vector<const FunctionSamples *> R;

  if (!DIL) {
    return R;
  }

  auto FSCompare = [](const FunctionSamples *L, const FunctionSamples *R) {
    assert(L && R && "Expect non-null FunctionSamples");
    if (L->getHeadSamplesEstimate() != R->getHeadSamplesEstimate())
      return L->getHeadSamplesEstimate() > R->getHeadSamplesEstimate();
    return L->getGUID() < R->getGUID();
  };

  if (FunctionSamples::ProfileIsCS) {
    auto CalleeSamples =
        ContextTracker->getIndirectCalleeContextSamplesFor(DIL);
    if (CalleeSamples.empty())
      return R;

    // For CSSPGO, we only use target context profile's entry count
    // as that already includes both inlined callee and non-inlined ones..
    Sum = 0;
    for (const auto *const FS : CalleeSamples) {
      Sum += FS->getHeadSamplesEstimate();
      R.push_back(FS);
    }
    llvm::sort(R, FSCompare);
    return R;
  }

  const FunctionSamples *FS = findFunctionSamples(Inst);
  if (FS == nullptr)
    return R;

  auto CallSite = FunctionSamples::getCallSiteIdentifier(DIL);
  Sum = 0;
  if (auto T = FS->findCallTargetMapAt(CallSite))
    for (const auto &T_C : *T)
      Sum += T_C.second;
  if (const FunctionSamplesMap *M = FS->findFunctionSamplesMapAt(CallSite)) {
    if (M->empty())
      return R;
    for (const auto &NameFS : *M) {
      Sum += NameFS.second.getHeadSamplesEstimate();
      R.push_back(&NameFS.second);
    }
    llvm::sort(R, FSCompare);
  }
  return R;
}

const FunctionSamples *
SampleProfileLoader::findFunctionSamples(const Instruction &Inst) const {
  if (FunctionSamples::ProfileIsProbeBased) {
    std::optional<PseudoProbe> Probe = extractProbe(Inst);
    if (!Probe)
      return nullptr;
  }

  const DILocation *DIL = Inst.getDebugLoc();
  if (!DIL)
    return Samples;

  auto it = DILocation2SampleMap.try_emplace(DIL,nullptr);
  if (it.second) {
    if (FunctionSamples::ProfileIsCS)
      it.first->second = ContextTracker->getContextSamplesFor(DIL);
    else
      it.first->second = Samples->findFunctionSamples(
          DIL, Reader->getRemapper(), &FuncNameToProfNameMap);
  }
  return it.first->second;
}

/// Check whether the indirect call promotion history of \p Inst allows
/// the promotion for \p Candidate.
/// If the profile count for the promotion candidate \p Candidate is
/// NOMORE_ICP_MAGICNUM, it means \p Candidate has already been promoted
/// for \p Inst. If we already have at least MaxNumPromotions
/// NOMORE_ICP_MAGICNUM count values in the value profile of \p Inst, we
/// cannot promote for \p Inst anymore.
static bool doesHistoryAllowICP(const Instruction &Inst, StringRef Candidate) {
  uint64_t TotalCount = 0;
  auto ValueData = getValueProfDataFromInst(Inst, IPVK_IndirectCallTarget,
                                            MaxNumPromotions, TotalCount, true);
  // No valid value profile so no promoted targets have been recorded
  // before. Ok to do ICP.
  if (ValueData.empty())
    return true;

  unsigned NumPromoted = 0;
  for (const auto &V : ValueData) {
    if (V.Count != NOMORE_ICP_MAGICNUM)
      continue;

    // If the promotion candidate has NOMORE_ICP_MAGICNUM count in the
    // metadata, it means the candidate has been promoted for this
    // indirect call.
    if (V.Value == Function::getGUIDAssumingExternalLinkage(Candidate))
      return false;
    NumPromoted++;
    // If already have MaxNumPromotions promotion, don't do it anymore.
    if (NumPromoted == MaxNumPromotions)
      return false;
  }
  return true;
}

/// Update indirect call target profile metadata for \p Inst.
/// Usually \p Sum is the sum of counts of all the targets for \p Inst.
/// If it is 0, it means updateIDTMetaData is used to mark a
/// certain target to be promoted already. If it is not zero,
/// we expect to use it to update the total count in the value profile.
static void
updateIDTMetaData(Instruction &Inst,
                  const SmallVectorImpl<InstrProfValueData> &CallTargets,
                  uint64_t Sum) {
  // Bail out early if MaxNumPromotions is zero.
  // This prevents allocating an array of zero length below.
  //
  // Note `updateIDTMetaData` is called in two places so check
  // `MaxNumPromotions` inside it.
  if (MaxNumPromotions == 0)
    return;
  // OldSum is the existing total count in the value profile data.
  uint64_t OldSum = 0;
  auto ValueData = getValueProfDataFromInst(Inst, IPVK_IndirectCallTarget,
                                            MaxNumPromotions, OldSum, true);

  DenseMap<uint64_t, uint64_t> ValueCountMap;
  if (Sum == 0) {
    assert((CallTargets.size() == 1 &&
            CallTargets[0].Count == NOMORE_ICP_MAGICNUM) &&
           "If sum is 0, assume only one element in CallTargets "
           "with count being NOMORE_ICP_MAGICNUM");
    // Initialize ValueCountMap with existing value profile data.
    for (const auto &V : ValueData)
      ValueCountMap[V.Value] = V.Count;
    auto Pair =
        ValueCountMap.try_emplace(CallTargets[0].Value, CallTargets[0].Count);
    // If the target already exists in value profile, decrease the total
    // count OldSum and reset the target's count to NOMORE_ICP_MAGICNUM.
    if (!Pair.second) {
      OldSum -= Pair.first->second;
      Pair.first->second = NOMORE_ICP_MAGICNUM;
    }
    Sum = OldSum;
  } else {
    // Initialize ValueCountMap with existing NOMORE_ICP_MAGICNUM
    // counts in the value profile.
    for (const auto &V : ValueData) {
      if (V.Count == NOMORE_ICP_MAGICNUM)
        ValueCountMap[V.Value] = V.Count;
    }

    for (const auto &Data : CallTargets) {
      auto Pair = ValueCountMap.try_emplace(Data.Value, Data.Count);
      if (Pair.second)
        continue;
      // The target represented by Data.Value has already been promoted.
      // Keep the count as NOMORE_ICP_MAGICNUM in the profile and decrease
      // Sum by Data.Count.
      assert(Sum >= Data.Count && "Sum should never be less than Data.Count");
      Sum -= Data.Count;
    }
  }

  SmallVector<InstrProfValueData, 8> NewCallTargets;
  for (const auto &ValueCount : ValueCountMap) {
    NewCallTargets.emplace_back(
        InstrProfValueData{ValueCount.first, ValueCount.second});
  }

  llvm::sort(NewCallTargets,
             [](const InstrProfValueData &L, const InstrProfValueData &R) {
               return std::tie(L.Count, L.Value) > std::tie(R.Count, R.Value);
             });

  uint32_t MaxMDCount =
      std::min(NewCallTargets.size(), static_cast<size_t>(MaxNumPromotions));
  annotateValueSite(*Inst.getParent()->getParent()->getParent(), Inst,
                    NewCallTargets, Sum, IPVK_IndirectCallTarget, MaxMDCount);
}

/// Attempt to promote indirect call and also inline the promoted call.
///
/// \param F  Caller function.
/// \param Candidate  ICP and inline candidate.
/// \param SumOrigin  Original sum of target counts for indirect call before
///                   promoting given candidate.
/// \param Sum        Prorated sum of remaining target counts for indirect call
///                   after promoting given candidate.
/// \param InlinedCallSite  Output vector for new call sites exposed after
/// inlining.
bool SampleProfileLoader::tryPromoteAndInlineCandidate(
    Function &F, InlineCandidate &Candidate, uint64_t SumOrigin, uint64_t &Sum,
    SmallVector<CallBase *, 8> *InlinedCallSite) {
  // Bail out early if sample-loader inliner is disabled.
  if (DisableSampleProfileInlining)
    return false;

  // Bail out early if MaxNumPromotions is zero.
  // This prevents allocating an array of zero length in callees below.
  if (MaxNumPromotions == 0)
    return false;
  auto CalleeFunctionName = Candidate.CalleeSamples->getFunction();
  auto R = SymbolMap.find(CalleeFunctionName);
  if (R == SymbolMap.end() || !R->second)
    return false;

  auto &CI = *Candidate.CallInstr;
  if (!doesHistoryAllowICP(CI, R->second->getName()))
    return false;

  const char *Reason = "Callee function not available";
  // R->getValue() != &F is to prevent promoting a recursive call.
  // If it is a recursive call, we do not inline it as it could bloat
  // the code exponentially. There is way to better handle this, e.g.
  // clone the caller first, and inline the cloned caller if it is
  // recursive. As llvm does not inline recursive calls, we will
  // simply ignore it instead of handling it explicitly.
  if (!R->second->isDeclaration() && R->second->getSubprogram() &&
      R->second->hasFnAttribute("use-sample-profile") &&
      R->second != &F && isLegalToPromote(CI, R->second, &Reason)) {
    // For promoted target, set its value with NOMORE_ICP_MAGICNUM count
    // in the value profile metadata so the target won't be promoted again.
    SmallVector<InstrProfValueData, 1> SortedCallTargets = {InstrProfValueData{
        Function::getGUIDAssumingExternalLinkage(R->second->getName()),
        NOMORE_ICP_MAGICNUM}};
    updateIDTMetaData(CI, SortedCallTargets, 0);

    auto *DI = &pgo::promoteIndirectCall(
        CI, R->second, Candidate.CallsiteCount, Sum, false, ORE);
    if (DI) {
      Sum -= Candidate.CallsiteCount;
      // Do not prorate the indirect callsite distribution since the original
      // distribution will be used to scale down non-promoted profile target
      // counts later. By doing this we lose track of the real callsite count
      // for the leftover indirect callsite as a trade off for accurate call
      // target counts.
      // TODO: Ideally we would have two separate factors, one for call site
      // counts and one is used to prorate call target counts.
      // Do not update the promoted direct callsite distribution at this
      // point since the original distribution combined with the callee profile
      // will be used to prorate callsites from the callee if inlined. Once not
      // inlined, the direct callsite distribution should be prorated so that
      // the it will reflect the real callsite counts.
      Candidate.CallInstr = DI;
      if (isa<CallInst>(DI) || isa<InvokeInst>(DI)) {
        bool Inlined = tryInlineCandidate(Candidate, InlinedCallSite);
        if (!Inlined) {
          // Prorate the direct callsite distribution so that it reflects real
          // callsite counts.
          setProbeDistributionFactor(
              *DI, static_cast<float>(Candidate.CallsiteCount) / SumOrigin);
        }
        return Inlined;
      }
    }
  } else {
    LLVM_DEBUG(dbgs() << "\nFailed to promote indirect call to "
                      << FunctionSamples::getCanonicalFnName(
                             Candidate.CallInstr->getName())<< " because "
                      << Reason << "\n");
  }
  return false;
}

bool SampleProfileLoader::shouldInlineColdCallee(CallBase &CallInst) {
  if (!ProfileSizeInline)
    return false;

  Function *Callee = CallInst.getCalledFunction();
  if (Callee == nullptr)
    return false;

  InlineCost Cost = getInlineCost(CallInst, getInlineParams(), GetTTI(*Callee),
                                  GetAC, GetTLI);

  if (Cost.isNever())
    return false;

  if (Cost.isAlways())
    return true;

  return Cost.getCost() <= SampleColdCallSiteThreshold;
}

void SampleProfileLoader::emitOptimizationRemarksForInlineCandidates(
    const SmallVectorImpl<CallBase *> &Candidates, const Function &F,
    bool Hot) {
  for (auto *I : Candidates) {
    Function *CalledFunction = I->getCalledFunction();
    if (CalledFunction) {
      ORE->emit(OptimizationRemarkAnalysis(getAnnotatedRemarkPassName(),
                                           "InlineAttempt", I->getDebugLoc(),
                                           I->getParent())
                << "previous inlining reattempted for "
                << (Hot ? "hotness: '" : "size: '")
                << ore::NV("Callee", CalledFunction) << "' into '"
                << ore::NV("Caller", &F) << "'");
    }
  }
}

void SampleProfileLoader::findExternalInlineCandidate(
    CallBase *CB, const FunctionSamples *Samples,
    DenseSet<GlobalValue::GUID> &InlinedGUIDs, uint64_t Threshold) {

  // If ExternalInlineAdvisor(ReplayInlineAdvisor) wants to inline an external
  // function make sure it's imported
  if (CB && getExternalInlineAdvisorShouldInline(*CB)) {
    // Samples may not exist for replayed function, if so
    // just add the direct GUID and move on
    if (!Samples) {
      InlinedGUIDs.insert(Function::getGUIDAssumingExternalLinkage(
          CB->getCalledFunction()->getName()));
      return;
    }
    // Otherwise, drop the threshold to import everything that we can
    Threshold = 0;
  }

  // In some rare cases, call instruction could be changed after being pushed
  // into inline candidate queue, this is because earlier inlining may expose
  // constant propagation which can change indirect call to direct call. When
  // this happens, we may fail to find matching function samples for the
  // candidate later, even if a match was found when the candidate was enqueued.
  if (!Samples)
    return;

  // For AutoFDO profile, retrieve candidate profiles by walking over
  // the nested inlinee profiles.
  if (!FunctionSamples::ProfileIsCS) {
    // Set threshold to zero to honor pre-inliner decision.
    if (UsePreInlinerDecision)
      Threshold = 0;
    Samples->findInlinedFunctions(InlinedGUIDs, SymbolMap, Threshold);
    return;
  }

  ContextTrieNode *Caller = ContextTracker->getContextNodeForProfile(Samples);
  std::queue<ContextTrieNode *> CalleeList;
  CalleeList.push(Caller);
  while (!CalleeList.empty()) {
    ContextTrieNode *Node = CalleeList.front();
    CalleeList.pop();
    FunctionSamples *CalleeSample = Node->getFunctionSamples();
    // For CSSPGO profile, retrieve candidate profile by walking over the
    // trie built for context profile. Note that also take call targets
    // even if callee doesn't have a corresponding context profile.
    if (!CalleeSample)
      continue;

    // If pre-inliner decision is used, honor that for importing as well.
    bool PreInline =
        UsePreInlinerDecision &&
        CalleeSample->getContext().hasAttribute(ContextShouldBeInlined);
    if (!PreInline && CalleeSample->getHeadSamplesEstimate() < Threshold)
      continue;

    Function *Func = SymbolMap.lookup(CalleeSample->getFunction());
    // Add to the import list only when it's defined out of module.
    if (!Func || Func->isDeclaration())
      InlinedGUIDs.insert(CalleeSample->getGUID());

    // Import hot CallTargets, which may not be available in IR because full
    // profile annotation cannot be done until backend compilation in ThinLTO.
    for (const auto &BS : CalleeSample->getBodySamples())
      for (const auto &TS : BS.second.getCallTargets())
        if (TS.second > Threshold) {
          const Function *Callee = SymbolMap.lookup(TS.first);
          if (!Callee || Callee->isDeclaration())
            InlinedGUIDs.insert(TS.first.getHashCode());
        }

    // Import hot child context profile associted with callees. Note that this
    // may have some overlap with the call target loop above, but doing this
    // based child context profile again effectively allow us to use the max of
    // entry count and call target count to determine importing.
    for (auto &Child : Node->getAllChildContext()) {
      ContextTrieNode *CalleeNode = &Child.second;
      CalleeList.push(CalleeNode);
    }
  }
}

/// Iteratively inline hot callsites of a function.
///
/// Iteratively traverse all callsites of the function \p F, so as to
/// find out callsites with corresponding inline instances.
///
/// For such callsites,
/// - If it is hot enough, inline the callsites and adds callsites of the callee
///   into the caller. If the call is an indirect call, first promote
///   it to direct call. Each indirect call is limited with a single target.
///
/// - If a callsite is not inlined, merge the its profile to the outline
///   version (if --sample-profile-merge-inlinee is true), or scale the
///   counters of standalone function based on the profile of inlined
///   instances (if --sample-profile-merge-inlinee is false).
///
///   Later passes may consume the updated profiles.
///
/// \param F function to perform iterative inlining.
/// \param InlinedGUIDs a set to be updated to include all GUIDs that are
///     inlined in the profiled binary.
///
/// \returns True if there is any inline happened.
bool SampleProfileLoader::inlineHotFunctions(
    Function &F, DenseSet<GlobalValue::GUID> &InlinedGUIDs) {
  // ProfAccForSymsInList is used in callsiteIsHot. The assertion makes sure
  // Profile symbol list is ignored when profile-sample-accurate is on.
  assert((!ProfAccForSymsInList ||
          (!ProfileSampleAccurate &&
           !F.hasFnAttribute("profile-sample-accurate"))) &&
         "ProfAccForSymsInList should be false when profile-sample-accurate "
         "is enabled");

  MapVector<CallBase *, const FunctionSamples *> LocalNotInlinedCallSites;
  bool Changed = false;
  bool LocalChanged = true;
  while (LocalChanged) {
    LocalChanged = false;
    SmallVector<CallBase *, 10> CIS;
    for (auto &BB : F) {
      bool Hot = false;
      SmallVector<CallBase *, 10> AllCandidates;
      SmallVector<CallBase *, 10> ColdCandidates;
      for (auto &I : BB) {
        const FunctionSamples *FS = nullptr;
        if (auto *CB = dyn_cast<CallBase>(&I)) {
          if (!isa<IntrinsicInst>(I)) {
            if ((FS = findCalleeFunctionSamples(*CB))) {
              assert((!FunctionSamples::UseMD5 || FS->GUIDToFuncNameMap) &&
                     "GUIDToFuncNameMap has to be populated");
              AllCandidates.push_back(CB);
              if (FS->getHeadSamplesEstimate() > 0 ||
                  FunctionSamples::ProfileIsCS)
                LocalNotInlinedCallSites.insert({CB, FS});
              if (callsiteIsHot(FS, PSI, ProfAccForSymsInList))
                Hot = true;
              else if (shouldInlineColdCallee(*CB))
                ColdCandidates.push_back(CB);
            } else if (getExternalInlineAdvisorShouldInline(*CB)) {
              AllCandidates.push_back(CB);
            }
          }
        }
      }
      if (Hot || ExternalInlineAdvisor) {
        CIS.insert(CIS.begin(), AllCandidates.begin(), AllCandidates.end());
        emitOptimizationRemarksForInlineCandidates(AllCandidates, F, true);
      } else {
        CIS.insert(CIS.begin(), ColdCandidates.begin(), ColdCandidates.end());
        emitOptimizationRemarksForInlineCandidates(ColdCandidates, F, false);
      }
    }
    for (CallBase *I : CIS) {
      Function *CalledFunction = I->getCalledFunction();
      InlineCandidate Candidate = {I, LocalNotInlinedCallSites.lookup(I),
                                   0 /* dummy count */,
                                   1.0 /* dummy distribution factor */};
      // Do not inline recursive calls.
      if (CalledFunction == &F)
        continue;
      if (I->isIndirectCall()) {
        uint64_t Sum;
        for (const auto *FS : findIndirectCallFunctionSamples(*I, Sum)) {
          uint64_t SumOrigin = Sum;
          if (LTOPhase == ThinOrFullLTOPhase::ThinLTOPreLink) {
            findExternalInlineCandidate(I, FS, InlinedGUIDs,
                                        PSI->getOrCompHotCountThreshold());
            continue;
          }
          if (!callsiteIsHot(FS, PSI, ProfAccForSymsInList))
            continue;

          Candidate = {I, FS, FS->getHeadSamplesEstimate(), 1.0};
          if (tryPromoteAndInlineCandidate(F, Candidate, SumOrigin, Sum)) {
            LocalNotInlinedCallSites.erase(I);
            LocalChanged = true;
          }
        }
      } else if (CalledFunction && CalledFunction->getSubprogram() &&
                 !CalledFunction->isDeclaration()) {
        if (tryInlineCandidate(Candidate)) {
          LocalNotInlinedCallSites.erase(I);
          LocalChanged = true;
        }
      } else if (LTOPhase == ThinOrFullLTOPhase::ThinLTOPreLink) {
        findExternalInlineCandidate(I, findCalleeFunctionSamples(*I),
                                    InlinedGUIDs,
                                    PSI->getOrCompHotCountThreshold());
      }
    }
    Changed |= LocalChanged;
  }

  // For CS profile, profile for not inlined context will be merged when
  // base profile is being retrieved.
  if (!FunctionSamples::ProfileIsCS)
    promoteMergeNotInlinedContextSamples(LocalNotInlinedCallSites, F);
  return Changed;
}

bool SampleProfileLoader::tryInlineCandidate(
    InlineCandidate &Candidate, SmallVector<CallBase *, 8> *InlinedCallSites) {
  // Do not attempt to inline a candidate if
  // --disable-sample-loader-inlining is true.
  if (DisableSampleProfileInlining)
    return false;

  CallBase &CB = *Candidate.CallInstr;
  Function *CalledFunction = CB.getCalledFunction();
  assert(CalledFunction && "Expect a callee with definition");
  DebugLoc DLoc = CB.getDebugLoc();
  BasicBlock *BB = CB.getParent();

  InlineCost Cost = shouldInlineCandidate(Candidate);
  if (Cost.isNever()) {
    ORE->emit(OptimizationRemarkAnalysis(getAnnotatedRemarkPassName(),
                                         "InlineFail", DLoc, BB)
              << "incompatible inlining");
    return false;
  }

  if (!Cost)
    return false;

  InlineFunctionInfo IFI(GetAC);
  IFI.UpdateProfile = false;
  InlineResult IR = InlineFunction(CB, IFI,
                                   /*MergeAttributes=*/true);
  if (!IR.isSuccess())
    return false;

  // The call to InlineFunction erases I, so we can't pass it here.
  emitInlinedIntoBasedOnCost(*ORE, DLoc, BB, *CalledFunction, *BB->getParent(),
                             Cost, true, getAnnotatedRemarkPassName());

  // Now populate the list of newly exposed call sites.
  if (InlinedCallSites) {
    InlinedCallSites->clear();
    llvm::append_range(*InlinedCallSites, IFI.InlinedCallSites);
  }

  if (FunctionSamples::ProfileIsCS)
    ContextTracker->markContextSamplesInlined(Candidate.CalleeSamples);
  ++NumCSInlined;

  // Prorate inlined probes for a duplicated inlining callsite which probably
  // has a distribution less than 100%. Samples for an inlinee should be
  // distributed among the copies of the original callsite based on each
  // callsite's distribution factor for counts accuracy. Note that an inlined
  // probe may come with its own distribution factor if it has been duplicated
  // in the inlinee body. The two factor are multiplied to reflect the
  // aggregation of duplication.
  if (Candidate.CallsiteDistribution < 1) {
    for (auto &I : IFI.InlinedCallSites) {
      if (std::optional<PseudoProbe> Probe = extractProbe(*I))
        setProbeDistributionFactor(*I, Probe->Factor *
                                   Candidate.CallsiteDistribution);
    }
    NumDuplicatedInlinesite++;
  }

  return true;
}

bool SampleProfileLoader::getInlineCandidate(InlineCandidate *NewCandidate,
                                             CallBase *CB) {
  assert(CB && "Expect non-null call instruction");

  if (isa<IntrinsicInst>(CB))
    return false;

  // Find the callee's profile. For indirect call, find hottest target profile.
  const FunctionSamples *CalleeSamples = findCalleeFunctionSamples(*CB);
  // If ExternalInlineAdvisor wants to inline this site, do so even
  // if Samples are not present.
  if (!CalleeSamples && !getExternalInlineAdvisorShouldInline(*CB))
    return false;

  float Factor = 1.0;
  if (std::optional<PseudoProbe> Probe = extractProbe(*CB))
    Factor = Probe->Factor;

  uint64_t CallsiteCount =
      CalleeSamples ? CalleeSamples->getHeadSamplesEstimate() * Factor : 0;
  *NewCandidate = {CB, CalleeSamples, CallsiteCount, Factor};
  return true;
}

std::optional<InlineCost>
SampleProfileLoader::getExternalInlineAdvisorCost(CallBase &CB) {
  std::unique_ptr<InlineAdvice> Advice = nullptr;
  if (ExternalInlineAdvisor) {
    Advice = ExternalInlineAdvisor->getAdvice(CB);
    if (Advice) {
      if (!Advice->isInliningRecommended()) {
        Advice->recordUnattemptedInlining();
        return InlineCost::getNever("not previously inlined");
      }
      Advice->recordInlining();
      return InlineCost::getAlways("previously inlined");
    }
  }

  return {};
}

bool SampleProfileLoader::getExternalInlineAdvisorShouldInline(CallBase &CB) {
  std::optional<InlineCost> Cost = getExternalInlineAdvisorCost(CB);
  return Cost ? !!*Cost : false;
}

InlineCost
SampleProfileLoader::shouldInlineCandidate(InlineCandidate &Candidate) {
  if (std::optional<InlineCost> ReplayCost =
          getExternalInlineAdvisorCost(*Candidate.CallInstr))
    return *ReplayCost;
  // Adjust threshold based on call site hotness, only do this for callsite
  // prioritized inliner because otherwise cost-benefit check is done earlier.
  int SampleThreshold = SampleColdCallSiteThreshold;
  if (CallsitePrioritizedInline) {
    if (Candidate.CallsiteCount > PSI->getHotCountThreshold())
      SampleThreshold = SampleHotCallSiteThreshold;
    else if (!ProfileSizeInline)
      return InlineCost::getNever("cold callsite");
  }

  Function *Callee = Candidate.CallInstr->getCalledFunction();
  assert(Callee && "Expect a definition for inline candidate of direct call");

  InlineParams Params = getInlineParams();
  // We will ignore the threshold from inline cost, so always get full cost.
  Params.ComputeFullInlineCost = true;
  Params.AllowRecursiveCall = AllowRecursiveInline;
  // Checks if there is anything in the reachable portion of the callee at
  // this callsite that makes this inlining potentially illegal. Need to
  // set ComputeFullInlineCost, otherwise getInlineCost may return early
  // when cost exceeds threshold without checking all IRs in the callee.
  // The acutal cost does not matter because we only checks isNever() to
  // see if it is legal to inline the callsite.
  InlineCost Cost = getInlineCost(*Candidate.CallInstr, Callee, Params,
                                  GetTTI(*Callee), GetAC, GetTLI);

  // Honor always inline and never inline from call analyzer
  if (Cost.isNever() || Cost.isAlways())
    return Cost;

  // With CSSPGO, the preinliner in llvm-profgen can estimate global inline
  // decisions based on hotness as well as accurate function byte sizes for
  // given context using function/inlinee sizes from previous build. It
  // stores the decision in profile, and also adjust/merge context profile
  // aiming at better context-sensitive post-inline profile quality, assuming
  // all inline decision estimates are going to be honored by compiler. Here
  // we replay that inline decision under `sample-profile-use-preinliner`.
  // Note that we don't need to handle negative decision from preinliner as
  // context profile for not inlined calls are merged by preinliner already.
  if (UsePreInlinerDecision && Candidate.CalleeSamples) {
    // Once two node are merged due to promotion, we're losing some context
    // so the original context-sensitive preinliner decision should be ignored
    // for SyntheticContext.
    SampleContext &Context = Candidate.CalleeSamples->getContext();
    if (!Context.hasState(SyntheticContext) &&
        Context.hasAttribute(ContextShouldBeInlined))
      return InlineCost::getAlways("preinliner");
  }

  // For old FDO inliner, we inline the call site if it is below hot threshold,
  // even if the function is hot based on sample profile data. This is to
  // prevent huge functions from being inlined.
  if (!CallsitePrioritizedInline) {
    return InlineCost::get(Cost.getCost(), SampleHotCallSiteThreshold);
  }

  // Otherwise only use the cost from call analyzer, but overwite threshold with
  // Sample PGO threshold.
  return InlineCost::get(Cost.getCost(), SampleThreshold);
}

bool SampleProfileLoader::inlineHotFunctionsWithPriority(
    Function &F, DenseSet<GlobalValue::GUID> &InlinedGUIDs) {
  // ProfAccForSymsInList is used in callsiteIsHot. The assertion makes sure
  // Profile symbol list is ignored when profile-sample-accurate is on.
  assert((!ProfAccForSymsInList ||
          (!ProfileSampleAccurate &&
           !F.hasFnAttribute("profile-sample-accurate"))) &&
         "ProfAccForSymsInList should be false when profile-sample-accurate "
         "is enabled");

  // Populating worklist with initial call sites from root inliner, along
  // with call site weights.
  CandidateQueue CQueue;
  InlineCandidate NewCandidate;
  for (auto &BB : F) {
    for (auto &I : BB) {
      auto *CB = dyn_cast<CallBase>(&I);
      if (!CB)
        continue;
      if (getInlineCandidate(&NewCandidate, CB))
        CQueue.push(NewCandidate);
    }
  }

  // Cap the size growth from profile guided inlining. This is needed even
  // though cost of each inline candidate already accounts for callee size,
  // because with top-down inlining, we can grow inliner size significantly
  // with large number of smaller inlinees each pass the cost check.
  assert(ProfileInlineLimitMax >= ProfileInlineLimitMin &&
         "Max inline size limit should not be smaller than min inline size "
         "limit.");
  unsigned SizeLimit = F.getInstructionCount() * ProfileInlineGrowthLimit;
  SizeLimit = std::min(SizeLimit, (unsigned)ProfileInlineLimitMax);
  SizeLimit = std::max(SizeLimit, (unsigned)ProfileInlineLimitMin);
  if (ExternalInlineAdvisor)
    SizeLimit = std::numeric_limits<unsigned>::max();

  MapVector<CallBase *, const FunctionSamples *> LocalNotInlinedCallSites;

  // Perform iterative BFS call site prioritized inlining
  bool Changed = false;
  while (!CQueue.empty() && F.getInstructionCount() < SizeLimit) {
    InlineCandidate Candidate = CQueue.top();
    CQueue.pop();
    CallBase *I = Candidate.CallInstr;
    Function *CalledFunction = I->getCalledFunction();

    if (CalledFunction == &F)
      continue;
    if (I->isIndirectCall()) {
      uint64_t Sum = 0;
      auto CalleeSamples = findIndirectCallFunctionSamples(*I, Sum);
      uint64_t SumOrigin = Sum;
      Sum *= Candidate.CallsiteDistribution;
      unsigned ICPCount = 0;
      for (const auto *FS : CalleeSamples) {
        // TODO: Consider disable pre-lTO ICP for MonoLTO as well
        if (LTOPhase == ThinOrFullLTOPhase::ThinLTOPreLink) {
          findExternalInlineCandidate(I, FS, InlinedGUIDs,
                                      PSI->getOrCompHotCountThreshold());
          continue;
        }
        uint64_t EntryCountDistributed =
            FS->getHeadSamplesEstimate() * Candidate.CallsiteDistribution;
        // In addition to regular inline cost check, we also need to make sure
        // ICP isn't introducing excessive speculative checks even if individual
        // target looks beneficial to promote and inline. That means we should
        // only do ICP when there's a small number dominant targets.
        if (ICPCount >= ProfileICPRelativeHotnessSkip &&
            EntryCountDistributed * 100 < SumOrigin * ProfileICPRelativeHotness)
          break;
        // TODO: Fix CallAnalyzer to handle all indirect calls.
        // For indirect call, we don't run CallAnalyzer to get InlineCost
        // before actual inlining. This is because we could see two different
        // types from the same definition, which makes CallAnalyzer choke as
        // it's expecting matching parameter type on both caller and callee
        // side. See example from PR18962 for the triggering cases (the bug was
        // fixed, but we generate different types).
        if (!PSI->isHotCount(EntryCountDistributed))
          break;
        SmallVector<CallBase *, 8> InlinedCallSites;
        // Attach function profile for promoted indirect callee, and update
        // call site count for the promoted inline candidate too.
        Candidate = {I, FS, EntryCountDistributed,
                     Candidate.CallsiteDistribution};
        if (tryPromoteAndInlineCandidate(F, Candidate, SumOrigin, Sum,
                                         &InlinedCallSites)) {
          for (auto *CB : InlinedCallSites) {
            if (getInlineCandidate(&NewCandidate, CB))
              CQueue.emplace(NewCandidate);
          }
          ICPCount++;
          Changed = true;
        } else if (!ContextTracker) {
          LocalNotInlinedCallSites.insert({I, FS});
        }
      }
    } else if (CalledFunction && CalledFunction->getSubprogram() &&
               !CalledFunction->isDeclaration()) {
      SmallVector<CallBase *, 8> InlinedCallSites;
      if (tryInlineCandidate(Candidate, &InlinedCallSites)) {
        for (auto *CB : InlinedCallSites) {
          if (getInlineCandidate(&NewCandidate, CB))
            CQueue.emplace(NewCandidate);
        }
        Changed = true;
      } else if (!ContextTracker) {
        LocalNotInlinedCallSites.insert({I, Candidate.CalleeSamples});
      }
    } else if (LTOPhase == ThinOrFullLTOPhase::ThinLTOPreLink) {
      findExternalInlineCandidate(I, findCalleeFunctionSamples(*I),
                                  InlinedGUIDs,
                                  PSI->getOrCompHotCountThreshold());
    }
  }

  if (!CQueue.empty()) {
    if (SizeLimit == (unsigned)ProfileInlineLimitMax)
      ++NumCSInlinedHitMaxLimit;
    else if (SizeLimit == (unsigned)ProfileInlineLimitMin)
      ++NumCSInlinedHitMinLimit;
    else
      ++NumCSInlinedHitGrowthLimit;
  }

  // For CS profile, profile for not inlined context will be merged when
  // base profile is being retrieved.
  if (!FunctionSamples::ProfileIsCS)
    promoteMergeNotInlinedContextSamples(LocalNotInlinedCallSites, F);
  return Changed;
}

void SampleProfileLoader::promoteMergeNotInlinedContextSamples(
    MapVector<CallBase *, const FunctionSamples *> NonInlinedCallSites,
    const Function &F) {
  // Accumulate not inlined callsite information into notInlinedSamples
  for (const auto &Pair : NonInlinedCallSites) {
    CallBase *I = Pair.first;
    Function *Callee = I->getCalledFunction();
    if (!Callee || Callee->isDeclaration())
      continue;

    ORE->emit(
        OptimizationRemarkAnalysis(getAnnotatedRemarkPassName(), "NotInline",
                                   I->getDebugLoc(), I->getParent())
        << "previous inlining not repeated: '" << ore::NV("Callee", Callee)
        << "' into '" << ore::NV("Caller", &F) << "'");

    ++NumCSNotInlined;
    const FunctionSamples *FS = Pair.second;
    if (FS->getTotalSamples() == 0 && FS->getHeadSamplesEstimate() == 0) {
      continue;
    }

    // Do not merge a context that is already duplicated into the base profile.
    if (FS->getContext().hasAttribute(sampleprof::ContextDuplicatedIntoBase))
      continue;

    if (ProfileMergeInlinee) {
      // A function call can be replicated by optimizations like callsite
      // splitting or jump threading and the replicates end up sharing the
      // sample nested callee profile instead of slicing the original
      // inlinee's profile. We want to do merge exactly once by filtering out
      // callee profiles with a non-zero head sample count.
      if (FS->getHeadSamples() == 0) {
        // Use entry samples as head samples during the merge, as inlinees
        // don't have head samples.
        const_cast<FunctionSamples *>(FS)->addHeadSamples(
            FS->getHeadSamplesEstimate());

        // Note that we have to do the merge right after processing function.
        // This allows OutlineFS's profile to be used for annotation during
        // top-down processing of functions' annotation.
        FunctionSamples *OutlineFS = Reader->getSamplesFor(*Callee);
        // If outlined function does not exist in the profile, add it to a
        // separate map so that it does not rehash the original profile.
        if (!OutlineFS)
          OutlineFS = &OutlineFunctionSamples[
              FunctionId(FunctionSamples::getCanonicalFnName(Callee->getName()))];
        OutlineFS->merge(*FS, 1);
        // Set outlined profile to be synthetic to not bias the inliner.
        OutlineFS->setContextSynthetic();
      }
    } else {
      auto pair =
          notInlinedCallInfo.try_emplace(Callee, NotInlinedProfileInfo{0});
      pair.first->second.entryCount += FS->getHeadSamplesEstimate();
    }
  }
}

/// Returns the sorted CallTargetMap \p M by count in descending order.
static SmallVector<InstrProfValueData, 2>
GetSortedValueDataFromCallTargets(const SampleRecord::CallTargetMap &M) {
  SmallVector<InstrProfValueData, 2> R;
  for (const auto &I : SampleRecord::sortCallTargets(M)) {
    R.emplace_back(
        InstrProfValueData{I.first.getHashCode(), I.second});
  }
  return R;
}

// Generate MD_prof metadata for every branch instruction using the
// edge weights computed during propagation.
void SampleProfileLoader::generateMDProfMetadata(Function &F) {
  // Generate MD_prof metadata for every branch instruction using the
  // edge weights computed during propagation.
  LLVM_DEBUG(dbgs() << "\nPropagation complete. Setting branch weights\n");
  LLVMContext &Ctx = F.getContext();
  MDBuilder MDB(Ctx);
  for (auto &BI : F) {
    BasicBlock *BB = &BI;

    if (BlockWeights[BB]) {
      for (auto &I : *BB) {
        if (!isa<CallInst>(I) && !isa<InvokeInst>(I))
          continue;
        if (!cast<CallBase>(I).getCalledFunction()) {
          const DebugLoc &DLoc = I.getDebugLoc();
          if (!DLoc)
            continue;
          const DILocation *DIL = DLoc;
          const FunctionSamples *FS = findFunctionSamples(I);
          if (!FS)
            continue;
          auto CallSite = FunctionSamples::getCallSiteIdentifier(DIL);
          ErrorOr<SampleRecord::CallTargetMap> T =
              FS->findCallTargetMapAt(CallSite);
          if (!T || T.get().empty())
            continue;
          if (FunctionSamples::ProfileIsProbeBased) {
            // Prorate the callsite counts based on the pre-ICP distribution
            // factor to reflect what is already done to the callsite before
            // ICP, such as calliste cloning.
            if (std::optional<PseudoProbe> Probe = extractProbe(I)) {
              if (Probe->Factor < 1)
                T = SampleRecord::adjustCallTargets(T.get(), Probe->Factor);
            }
          }
          SmallVector<InstrProfValueData, 2> SortedCallTargets =
              GetSortedValueDataFromCallTargets(T.get());
          uint64_t Sum = 0;
          for (const auto &C : T.get())
            Sum += C.second;
          // With CSSPGO all indirect call targets are counted torwards the
          // original indirect call site in the profile, including both
          // inlined and non-inlined targets.
          if (!FunctionSamples::ProfileIsCS) {
            if (const FunctionSamplesMap *M =
                    FS->findFunctionSamplesMapAt(CallSite)) {
              for (const auto &NameFS : *M)
                Sum += NameFS.second.getHeadSamplesEstimate();
            }
          }
          if (Sum)
            updateIDTMetaData(I, SortedCallTargets, Sum);
          else if (OverwriteExistingWeights)
            I.setMetadata(LLVMContext::MD_prof, nullptr);
        } else if (!isa<IntrinsicInst>(&I)) {
          setBranchWeights(
              I, ArrayRef<uint32_t>{static_cast<uint32_t>(BlockWeights[BB])},
              /*IsExpected=*/false);
        }
      }
    } else if (OverwriteExistingWeights || ProfileSampleBlockAccurate) {
      // Set profile metadata (possibly annotated by LTO prelink) to zero or
      // clear it for cold code.
      for (auto &I : *BB) {
        if (isa<CallInst>(I) || isa<InvokeInst>(I)) {
          if (cast<CallBase>(I).isIndirectCall()) {
            I.setMetadata(LLVMContext::MD_prof, nullptr);
          } else {
            setBranchWeights(I, ArrayRef<uint32_t>{uint32_t(0)},
                             /*IsExpected=*/false);
          }
        }
      }
    }

    Instruction *TI = BB->getTerminator();
    if (TI->getNumSuccessors() == 1)
      continue;
    if (!isa<BranchInst>(TI) && !isa<SwitchInst>(TI) &&
        !isa<IndirectBrInst>(TI))
      continue;

    DebugLoc BranchLoc = TI->getDebugLoc();
    LLVM_DEBUG(dbgs() << "\nGetting weights for branch at line "
                      << ((BranchLoc) ? Twine(BranchLoc.getLine())
                                      : Twine("<UNKNOWN LOCATION>"))
                      << ".\n");
    SmallVector<uint32_t, 4> Weights;
    uint32_t MaxWeight = 0;
    Instruction *MaxDestInst;
    // Since profi treats multiple edges (multiway branches) as a single edge,
    // we need to distribute the computed weight among the branches. We do
    // this by evenly splitting the edge weight among destinations.
    DenseMap<const BasicBlock *, uint64_t> EdgeMultiplicity;
    std::vector<uint64_t> EdgeIndex;
    if (SampleProfileUseProfi) {
      EdgeIndex.resize(TI->getNumSuccessors());
      for (unsigned I = 0; I < TI->getNumSuccessors(); ++I) {
        const BasicBlock *Succ = TI->getSuccessor(I);
        EdgeIndex[I] = EdgeMultiplicity[Succ];
        EdgeMultiplicity[Succ]++;
      }
    }
    for (unsigned I = 0; I < TI->getNumSuccessors(); ++I) {
      BasicBlock *Succ = TI->getSuccessor(I);
      Edge E = std::make_pair(BB, Succ);
      uint64_t Weight = EdgeWeights[E];
      LLVM_DEBUG(dbgs() << "\t"; printEdgeWeight(dbgs(), E));
      // Use uint32_t saturated arithmetic to adjust the incoming weights,
      // if needed. Sample counts in profiles are 64-bit unsigned values,
      // but internally branch weights are expressed as 32-bit values.
      if (Weight > std::numeric_limits<uint32_t>::max()) {
        LLVM_DEBUG(dbgs() << " (saturated due to uint32_t overflow)\n");
        Weight = std::numeric_limits<uint32_t>::max();
      }
      if (!SampleProfileUseProfi) {
        // Weight is added by one to avoid propagation errors introduced by
        // 0 weights.
        Weights.push_back(static_cast<uint32_t>(
            Weight == std::numeric_limits<uint32_t>::max() ? Weight
                                                           : Weight + 1));
      } else {
        // Profi creates proper weights that do not require "+1" adjustments but
        // we evenly split the weight among branches with the same destination.
        uint64_t W = Weight / EdgeMultiplicity[Succ];
        // Rounding up, if needed, so that first branches are hotter.
        if (EdgeIndex[I] < Weight % EdgeMultiplicity[Succ])
          W++;
        Weights.push_back(static_cast<uint32_t>(W));
      }
      if (Weight != 0) {
        if (Weight > MaxWeight) {
          MaxWeight = Weight;
          MaxDestInst = &*Succ->getFirstNonPHIOrDbgOrLifetime();
        }
      }
    }

    misexpect::checkExpectAnnotations(*TI, Weights, /*IsFrontend=*/false);

    uint64_t TempWeight;
    // Only set weights if there is at least one non-zero weight.
    // In any other case, let the analyzer set weights.
    // Do not set weights if the weights are present unless under
    // OverwriteExistingWeights. In ThinLTO, the profile annotation is done
    // twice. If the first annotation already set the weights, the second pass
    // does not need to set it. With OverwriteExistingWeights, Blocks with zero
    // weight should have their existing metadata (possibly annotated by LTO
    // prelink) cleared.
    if (MaxWeight > 0 &&
        (!TI->extractProfTotalWeight(TempWeight) || OverwriteExistingWeights)) {
      LLVM_DEBUG(dbgs() << "SUCCESS. Found non-zero weights.\n");
      setBranchWeights(*TI, Weights, /*IsExpected=*/false);
      ORE->emit([&]() {
        return OptimizationRemark(DEBUG_TYPE, "PopularDest", MaxDestInst)
               << "most popular destination for conditional branches at "
               << ore::NV("CondBranchesLoc", BranchLoc);
      });
    } else {
      if (OverwriteExistingWeights) {
        TI->setMetadata(LLVMContext::MD_prof, nullptr);
        LLVM_DEBUG(dbgs() << "CLEARED. All branch weights are zero.\n");
      } else {
        LLVM_DEBUG(dbgs() << "SKIPPED. All branch weights are zero.\n");
      }
    }
  }
}

/// Once all the branch weights are computed, we emit the MD_prof
/// metadata on BB using the computed values for each of its branches.
///
/// \param F The function to query.
///
/// \returns true if \p F was modified. Returns false, otherwise.
bool SampleProfileLoader::emitAnnotations(Function &F) {
  bool Changed = false;

  if (FunctionSamples::ProfileIsProbeBased) {
    LLVM_DEBUG({
      if (!ProbeManager->getDesc(F))
        dbgs() << "Probe descriptor missing for Function " << F.getName()
               << "\n";
    });

    if (ProbeManager->profileIsValid(F, *Samples)) {
      ++NumMatchedProfile;
    } else {
      ++NumMismatchedProfile;
      LLVM_DEBUG(
          dbgs() << "Profile is invalid due to CFG mismatch for Function "
                 << F.getName() << "\n");
      if (!SalvageStaleProfile)
        return false;
    }
  } else {
    if (getFunctionLoc(F) == 0)
      return false;

    LLVM_DEBUG(dbgs() << "Line number for the first instruction in "
                      << F.getName() << ": " << getFunctionLoc(F) << "\n");
  }

  DenseSet<GlobalValue::GUID> InlinedGUIDs;
  if (CallsitePrioritizedInline)
    Changed |= inlineHotFunctionsWithPriority(F, InlinedGUIDs);
  else
    Changed |= inlineHotFunctions(F, InlinedGUIDs);

  Changed |= computeAndPropagateWeights(F, InlinedGUIDs);

  if (Changed)
    generateMDProfMetadata(F);

  emitCoverageRemarks(F);
  return Changed;
}

std::unique_ptr<ProfiledCallGraph>
SampleProfileLoader::buildProfiledCallGraph(Module &M) {
  std::unique_ptr<ProfiledCallGraph> ProfiledCG;
  if (FunctionSamples::ProfileIsCS)
    ProfiledCG = std::make_unique<ProfiledCallGraph>(*ContextTracker);
  else
    ProfiledCG = std::make_unique<ProfiledCallGraph>(Reader->getProfiles());

  // Add all functions into the profiled call graph even if they are not in
  // the profile. This makes sure functions missing from the profile still
  // gets a chance to be processed.
  for (Function &F : M) {
    if (skipProfileForFunction(F))
      continue;
    ProfiledCG->addProfiledFunction(
          getRepInFormat(FunctionSamples::getCanonicalFnName(F)));
  }

  return ProfiledCG;
}

std::vector<Function *>
SampleProfileLoader::buildFunctionOrder(Module &M, LazyCallGraph &CG) {
  std::vector<Function *> FunctionOrderList;
  FunctionOrderList.reserve(M.size());

  if (!ProfileTopDownLoad && UseProfiledCallGraph)
    errs() << "WARNING: -use-profiled-call-graph ignored, should be used "
              "together with -sample-profile-top-down-load.\n";

  if (!ProfileTopDownLoad) {
    if (ProfileMergeInlinee) {
      // Disable ProfileMergeInlinee if profile is not loaded in top down order,
      // because the profile for a function may be used for the profile
      // annotation of its outline copy before the profile merging of its
      // non-inlined inline instances, and that is not the way how
      // ProfileMergeInlinee is supposed to work.
      ProfileMergeInlinee = false;
    }

    for (Function &F : M)
      if (!skipProfileForFunction(F))
        FunctionOrderList.push_back(&F);
    return FunctionOrderList;
  }

  if (UseProfiledCallGraph || (FunctionSamples::ProfileIsCS &&
                               !UseProfiledCallGraph.getNumOccurrences())) {
    // Use profiled call edges to augment the top-down order. There are cases
    // that the top-down order computed based on the static call graph doesn't
    // reflect real execution order. For example
    //
    // 1. Incomplete static call graph due to unknown indirect call targets.
    //    Adjusting the order by considering indirect call edges from the
    //    profile can enable the inlining of indirect call targets by allowing
    //    the caller processed before them.
    // 2. Mutual call edges in an SCC. The static processing order computed for
    //    an SCC may not reflect the call contexts in the context-sensitive
    //    profile, thus may cause potential inlining to be overlooked. The
    //    function order in one SCC is being adjusted to a top-down order based
    //    on the profile to favor more inlining. This is only a problem with CS
    //    profile.
    // 3. Transitive indirect call edges due to inlining. When a callee function
    //    (say B) is inlined into a caller function (say A) in LTO prelink,
    //    every call edge originated from the callee B will be transferred to
    //    the caller A. If any transferred edge (say A->C) is indirect, the
    //    original profiled indirect edge B->C, even if considered, would not
    //    enforce a top-down order from the caller A to the potential indirect
    //    call target C in LTO postlink since the inlined callee B is gone from
    //    the static call graph.
    // 4. #3 can happen even for direct call targets, due to functions defined
    //    in header files. A header function (say A), when included into source
    //    files, is defined multiple times but only one definition survives due
    //    to ODR. Therefore, the LTO prelink inlining done on those dropped
    //    definitions can be useless based on a local file scope. More
    //    importantly, the inlinee (say B), once fully inlined to a
    //    to-be-dropped A, will have no profile to consume when its outlined
    //    version is compiled. This can lead to a profile-less prelink
    //    compilation for the outlined version of B which may be called from
    //    external modules. while this isn't easy to fix, we rely on the
    //    postlink AutoFDO pipeline to optimize B. Since the survived copy of
    //    the A can be inlined in its local scope in prelink, it may not exist
    //    in the merged IR in postlink, and we'll need the profiled call edges
    //    to enforce a top-down order for the rest of the functions.
    //
    // Considering those cases, a profiled call graph completely independent of
    // the static call graph is constructed based on profile data, where
    // function objects are not even needed to handle case #3 and case 4.
    //
    // Note that static callgraph edges are completely ignored since they
    // can be conflicting with profiled edges for cyclic SCCs and may result in
    // an SCC order incompatible with profile-defined one. Using strictly
    // profile order ensures a maximum inlining experience. On the other hand,
    // static call edges are not so important when they don't correspond to a
    // context in the profile.

    std::unique_ptr<ProfiledCallGraph> ProfiledCG = buildProfiledCallGraph(M);
    scc_iterator<ProfiledCallGraph *> CGI = scc_begin(ProfiledCG.get());
    while (!CGI.isAtEnd()) {
      auto Range = *CGI;
      if (SortProfiledSCC) {
        // Sort nodes in one SCC based on callsite hotness.
        scc_member_iterator<ProfiledCallGraph *> SI(*CGI);
        Range = *SI;
      }
      for (auto *Node : Range) {
        Function *F = SymbolMap.lookup(Node->Name);
        if (F && !skipProfileForFunction(*F))
          FunctionOrderList.push_back(F);
      }
      ++CGI;
    }
    std::reverse(FunctionOrderList.begin(), FunctionOrderList.end());
  } else
    buildTopDownFuncOrder(CG, FunctionOrderList);

  LLVM_DEBUG({
    dbgs() << "Function processing order:\n";
    for (auto F : FunctionOrderList) {
      dbgs() << F->getName() << "\n";
    }
  });

  return FunctionOrderList;
}

bool SampleProfileLoader::doInitialization(Module &M,
                                           FunctionAnalysisManager *FAM) {
  auto &Ctx = M.getContext();

  auto ReaderOrErr = SampleProfileReader::create(
      Filename, Ctx, *FS, FSDiscriminatorPass::Base, RemappingFilename);
  if (std::error_code EC = ReaderOrErr.getError()) {
    std::string Msg = "Could not open profile: " + EC.message();
    Ctx.diagnose(DiagnosticInfoSampleProfile(Filename, Msg));
    return false;
  }
  Reader = std::move(ReaderOrErr.get());
  Reader->setSkipFlatProf(LTOPhase == ThinOrFullLTOPhase::ThinLTOPostLink);
  // set module before reading the profile so reader may be able to only
  // read the function profiles which are used by the current module.
  Reader->setModule(&M);
  if (std::error_code EC = Reader->read()) {
    std::string Msg = "profile reading failed: " + EC.message();
    Ctx.diagnose(DiagnosticInfoSampleProfile(Filename, Msg));
    return false;
  }

  PSL = Reader->getProfileSymbolList();

  if (DisableSampleLoaderInlining.getNumOccurrences())
    DisableSampleProfileInlining = DisableSampleLoaderInlining;

  if (UseFlattenedProfile)
    ProfileConverter::flattenProfile(Reader->getProfiles(),
                                     Reader->profileIsCS());

  // While profile-sample-accurate is on, ignore symbol list.
  ProfAccForSymsInList =
      ProfileAccurateForSymsInList && PSL && !ProfileSampleAccurate;
  if (ProfAccForSymsInList) {
    NamesInProfile.clear();
    GUIDsInProfile.clear();
    if (auto NameTable = Reader->getNameTable()) {
      if (FunctionSamples::UseMD5) {
        for (auto Name : *NameTable)
          GUIDsInProfile.insert(Name.getHashCode());
      } else {
        for (auto Name : *NameTable)
          NamesInProfile.insert(Name.stringRef());
      }
    }
    CoverageTracker.setProfAccForSymsInList(true);
  }

  if (FAM && !ProfileInlineReplayFile.empty()) {
    ExternalInlineAdvisor = getReplayInlineAdvisor(
        M, *FAM, Ctx, /*OriginalAdvisor=*/nullptr,
        ReplayInlinerSettings{ProfileInlineReplayFile,
                              ProfileInlineReplayScope,
                              ProfileInlineReplayFallback,
                              {ProfileInlineReplayFormat}},
        /*EmitRemarks=*/false, InlineContext{LTOPhase, InlinePass::ReplaySampleProfileInliner});
  }

  // Apply tweaks if context-sensitive or probe-based profile is available.
  if (Reader->profileIsCS() || Reader->profileIsPreInlined() ||
      Reader->profileIsProbeBased()) {
    if (!UseIterativeBFIInference.getNumOccurrences())
      UseIterativeBFIInference = true;
    if (!SampleProfileUseProfi.getNumOccurrences())
      SampleProfileUseProfi = true;
    if (!EnableExtTspBlockPlacement.getNumOccurrences())
      EnableExtTspBlockPlacement = true;
    // Enable priority-base inliner and size inline by default for CSSPGO.
    if (!ProfileSizeInline.getNumOccurrences())
      ProfileSizeInline = true;
    if (!CallsitePrioritizedInline.getNumOccurrences())
      CallsitePrioritizedInline = true;
    // For CSSPGO, we also allow recursive inline to best use context profile.
    if (!AllowRecursiveInline.getNumOccurrences())
      AllowRecursiveInline = true;

    if (Reader->profileIsPreInlined()) {
      if (!UsePreInlinerDecision.getNumOccurrences())
        UsePreInlinerDecision = true;
    }

    // Enable stale profile matching by default for probe-based profile.
    // Currently the matching relies on if the checksum mismatch is detected,
    // which is currently only available for pseudo-probe mode. Removing the
    // checksum check could cause regressions for some cases, so further tuning
    // might be needed if we want to enable it for all cases.
    if (Reader->profileIsProbeBased()) {
      if (!SalvageStaleProfile.getNumOccurrences())
        SalvageStaleProfile = true;
      if (!SalvageUnusedProfile.getNumOccurrences())
        SalvageUnusedProfile = true;
    }

    if (!Reader->profileIsCS()) {
      // Non-CS profile should be fine without a function size budget for the
      // inliner since the contexts in the profile are either all from inlining
      // in the prevoius build or pre-computed by the preinliner with a size
      // cap, thus they are bounded.
      if (!ProfileInlineLimitMin.getNumOccurrences())
        ProfileInlineLimitMin = std::numeric_limits<unsigned>::max();
      if (!ProfileInlineLimitMax.getNumOccurrences())
        ProfileInlineLimitMax = std::numeric_limits<unsigned>::max();
    }
  }

  if (Reader->profileIsCS()) {
    // Tracker for profiles under different context
    ContextTracker = std::make_unique<SampleContextTracker>(
        Reader->getProfiles(), &GUIDToFuncNameMap);
  }

  // Load pseudo probe descriptors for probe-based function samples.
  if (Reader->profileIsProbeBased()) {
    ProbeManager = std::make_unique<PseudoProbeManager>(M);
    if (!ProbeManager->moduleIsProbed(M)) {
      const char *Msg =
          "Pseudo-probe-based profile requires SampleProfileProbePass";
      Ctx.diagnose(DiagnosticInfoSampleProfile(M.getModuleIdentifier(), Msg,
                                               DS_Warning));
      return false;
    }
  }

  if (ReportProfileStaleness || PersistProfileStaleness ||
      SalvageStaleProfile) {
    MatchingManager = std::make_unique<SampleProfileMatcher>(
        M, *Reader, CG, ProbeManager.get(), LTOPhase, SymbolMap, PSL,
        FuncNameToProfNameMap);
  }

  return true;
}

// Note that this is a module-level check. Even if one module is errored out,
// the entire build will be errored out. However, the user could make big
// changes to functions in single module but those changes might not be
// performance significant to the whole binary. Therefore, to avoid those false
// positives, we select a reasonable big set of hot functions that are supposed
// to be globally performance significant, only compute and check the mismatch
// within those functions. The function selection is based on two criteria:
// 1) The function is hot enough, which is tuned by a hotness-based
// flag(HotFuncCutoffForStalenessError). 2) The num of function is large enough
// which is tuned by the MinfuncsForStalenessError flag.
bool SampleProfileLoader::rejectHighStalenessProfile(
    Module &M, ProfileSummaryInfo *PSI, const SampleProfileMap &Profiles) {
  assert(FunctionSamples::ProfileIsProbeBased &&
         "Only support for probe-based profile");
  uint64_t TotalHotFunc = 0;
  uint64_t NumMismatchedFunc = 0;
  for (const auto &I : Profiles) {
    const auto &FS = I.second;
    const auto *FuncDesc = ProbeManager->getDesc(FS.getGUID());
    if (!FuncDesc)
      continue;

    // Use a hotness-based threshold to control the function selection.
    if (!PSI->isHotCountNthPercentile(HotFuncCutoffForStalenessError,
                                      FS.getTotalSamples()))
      continue;

    TotalHotFunc++;
    if (ProbeManager->profileIsHashMismatched(*FuncDesc, FS))
      NumMismatchedFunc++;
  }
  // Make sure that the num of selected function is not too small to distinguish
  // from the user's benign changes.
  if (TotalHotFunc < MinfuncsForStalenessError)
    return false;

  // Finally check the mismatch percentage against the threshold.
  if (NumMismatchedFunc * 100 >=
      TotalHotFunc * PrecentMismatchForStalenessError) {
    auto &Ctx = M.getContext();
    const char *Msg =
        "The input profile significantly mismatches current source code. "
        "Please recollect profile to avoid performance regression.";
    Ctx.diagnose(DiagnosticInfoSampleProfile(M.getModuleIdentifier(), Msg));
    return true;
  }
  return false;
}

void SampleProfileLoader::removePseudoProbeInstsDiscriminator(Module &M) {
  for (auto &F : M) {
    std::vector<Instruction *> InstsToDel;
    for (auto &BB : F) {
      for (auto &I : BB) {
        if (isa<PseudoProbeInst>(&I))
          InstsToDel.push_back(&I);
        else if (isa<CallBase>(&I))
          if (const DILocation *DIL = I.getDebugLoc().get()) {
            // Restore dwarf discriminator for call.
            unsigned Discriminator = DIL->getDiscriminator();
            if (DILocation::isPseudoProbeDiscriminator(Discriminator)) {
              std::optional<uint32_t> DwarfDiscriminator =
                  PseudoProbeDwarfDiscriminator::extractDwarfBaseDiscriminator(
                      Discriminator);
              I.setDebugLoc(
                  DIL->cloneWithDiscriminator(DwarfDiscriminator.value_or(0)));
            }
          }
      }
    }
    for (auto *I : InstsToDel)
      I->eraseFromParent();
  }
}

bool SampleProfileLoader::runOnModule(Module &M, ModuleAnalysisManager &AM,
                                      ProfileSummaryInfo *_PSI) {
  GUIDToFuncNameMapper Mapper(M, *Reader, GUIDToFuncNameMap);

  PSI = _PSI;
  if (M.getProfileSummary(/* IsCS */ false) == nullptr) {
    M.setProfileSummary(Reader->getSummary().getMD(M.getContext()),
                        ProfileSummary::PSK_Sample);
    PSI->refresh();
  }

  if (FunctionSamples::ProfileIsProbeBased &&
      rejectHighStalenessProfile(M, PSI, Reader->getProfiles()))
    return false;

  auto Remapper = Reader->getRemapper();
  // Populate the symbol map.
  for (const auto &N_F : M.getValueSymbolTable()) {
    StringRef OrigName = N_F.getKey();
    Function *F = dyn_cast<Function>(N_F.getValue());
    if (F == nullptr || OrigName.empty())
      continue;
    SymbolMap[FunctionId(OrigName)] = F;
    StringRef NewName = FunctionSamples::getCanonicalFnName(*F);
    if (OrigName != NewName && !NewName.empty()) {
      auto r = SymbolMap.emplace(FunctionId(NewName), F);
      // Failiing to insert means there is already an entry in SymbolMap,
      // thus there are multiple functions that are mapped to the same
      // stripped name. In this case of name conflicting, set the value
      // to nullptr to avoid confusion.
      if (!r.second)
        r.first->second = nullptr;
      OrigName = NewName;
    }
    // Insert the remapped names into SymbolMap.
    if (Remapper) {
      if (auto MapName = Remapper->lookUpNameInProfile(OrigName)) {
        if (*MapName != OrigName && !MapName->empty())
          SymbolMap.emplace(FunctionId(*MapName), F);
      }
    }
  }

  // Stale profile matching.
  if (ReportProfileStaleness || PersistProfileStaleness ||
      SalvageStaleProfile) {
    MatchingManager->runOnModule();
    MatchingManager->clearMatchingData();
  }
  assert(SymbolMap.count(FunctionId()) == 0 &&
         "No empty StringRef should be added in SymbolMap");
  assert((SalvageUnusedProfile || FuncNameToProfNameMap.empty()) &&
         "FuncNameToProfNameMap is not empty when --salvage-unused-profile is "
         "not enabled");

  bool retval = false;
  for (auto *F : buildFunctionOrder(M, CG)) {
    assert(!F->isDeclaration());
    clearFunctionData();
    retval |= runOnFunction(*F, AM);
  }

  // Account for cold calls not inlined....
  if (!FunctionSamples::ProfileIsCS)
    for (const std::pair<Function *, NotInlinedProfileInfo> &pair :
         notInlinedCallInfo)
      updateProfileCallee(pair.first, pair.second.entryCount);

  if (RemoveProbeAfterProfileAnnotation &&
      FunctionSamples::ProfileIsProbeBased) {
    removePseudoProbeInstsDiscriminator(M);
    if (auto *FuncInfo = M.getNamedMetadata(PseudoProbeDescMetadataName))
      M.eraseNamedMetadata(FuncInfo);
  }

  return retval;
}

bool SampleProfileLoader::runOnFunction(Function &F,
                                        ModuleAnalysisManager &AM) {
  LLVM_DEBUG(dbgs() << "\n\nProcessing Function " << F.getName() << "\n");
  DILocation2SampleMap.clear();
  // By default the entry count is initialized to -1, which will be treated
  // conservatively by getEntryCount as the same as unknown (None). This is
  // to avoid newly added code to be treated as cold. If we have samples
  // this will be overwritten in emitAnnotations.
  uint64_t initialEntryCount = -1;

  ProfAccForSymsInList = ProfileAccurateForSymsInList && PSL;
  if (ProfileSampleAccurate || F.hasFnAttribute("profile-sample-accurate")) {
    // initialize all the function entry counts to 0. It means all the
    // functions without profile will be regarded as cold.
    initialEntryCount = 0;
    // profile-sample-accurate is a user assertion which has a higher precedence
    // than symbol list. When profile-sample-accurate is on, ignore symbol list.
    ProfAccForSymsInList = false;
  }
  CoverageTracker.setProfAccForSymsInList(ProfAccForSymsInList);

  // PSL -- profile symbol list include all the symbols in sampled binary.
  // If ProfileAccurateForSymsInList is enabled, PSL is used to treat
  // old functions without samples being cold, without having to worry
  // about new and hot functions being mistakenly treated as cold.
  if (ProfAccForSymsInList) {
    // Initialize the entry count to 0 for functions in the list.
    if (PSL->contains(F.getName()))
      initialEntryCount = 0;

    // Function in the symbol list but without sample will be regarded as
    // cold. To minimize the potential negative performance impact it could
    // have, we want to be a little conservative here saying if a function
    // shows up in the profile, no matter as outline function, inline instance
    // or call targets, treat the function as not being cold. This will handle
    // the cases such as most callsites of a function are inlined in sampled
    // binary but not inlined in current build (because of source code drift,
    // imprecise debug information, or the callsites are all cold individually
    // but not cold accumulatively...), so the outline function showing up as
    // cold in sampled binary will actually not be cold after current build.
    StringRef CanonName = FunctionSamples::getCanonicalFnName(F);
    if ((FunctionSamples::UseMD5 &&
         GUIDsInProfile.count(
             Function::getGUIDAssumingExternalLinkage(CanonName))) ||
        (!FunctionSamples::UseMD5 && NamesInProfile.count(CanonName)))
      initialEntryCount = -1;
  }

  // Initialize entry count when the function has no existing entry
  // count value.
  if (!F.getEntryCount())
    F.setEntryCount(ProfileCount(initialEntryCount, Function::PCT_Real));
  auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(*F.getParent())
                  .getManager();
  ORE = &FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);

  if (FunctionSamples::ProfileIsCS)
    Samples = ContextTracker->getBaseSamplesFor(F);
  else {
    Samples = Reader->getSamplesFor(F);
    // Try search in previously inlined functions that were split or duplicated
    // into base.
    if (!Samples) {
      StringRef CanonName = FunctionSamples::getCanonicalFnName(F);
      auto It = OutlineFunctionSamples.find(FunctionId(CanonName));
      if (It != OutlineFunctionSamples.end()) {
        Samples = &It->second;
      } else if (auto Remapper = Reader->getRemapper()) {
        if (auto RemppedName = Remapper->lookUpNameInProfile(CanonName)) {
          It = OutlineFunctionSamples.find(FunctionId(*RemppedName));
          if (It != OutlineFunctionSamples.end())
            Samples = &It->second;
        }
      }
    }
  }

  if (Samples && !Samples->empty())
    return emitAnnotations(F);
  return false;
}
SampleProfileLoaderPass::SampleProfileLoaderPass(
    std::string File, std::string RemappingFile, ThinOrFullLTOPhase LTOPhase,
    IntrusiveRefCntPtr<vfs::FileSystem> FS, bool DisableSampleProfileInlining,
    bool UseFlattenedProfile)
    : ProfileFileName(File), ProfileRemappingFileName(RemappingFile),
      LTOPhase(LTOPhase), FS(std::move(FS)),
      DisableSampleProfileInlining(DisableSampleProfileInlining),
      UseFlattenedProfile(UseFlattenedProfile) {}

PreservedAnalyses SampleProfileLoaderPass::run(Module &M,
                                               ModuleAnalysisManager &AM) {
  FunctionAnalysisManager &FAM =
      AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();

  auto GetAssumptionCache = [&](Function &F) -> AssumptionCache & {
    return FAM.getResult<AssumptionAnalysis>(F);
  };
  auto GetTTI = [&](Function &F) -> TargetTransformInfo & {
    return FAM.getResult<TargetIRAnalysis>(F);
  };
  auto GetTLI = [&](Function &F) -> const TargetLibraryInfo & {
    return FAM.getResult<TargetLibraryAnalysis>(F);
  };

  if (!FS)
    FS = vfs::getRealFileSystem();
  LazyCallGraph &CG = AM.getResult<LazyCallGraphAnalysis>(M);

  SampleProfileLoader SampleLoader(
      ProfileFileName.empty() ? SampleProfileFile : ProfileFileName,
      ProfileRemappingFileName.empty() ? SampleProfileRemappingFile
                                       : ProfileRemappingFileName,
      LTOPhase, FS, GetAssumptionCache, GetTTI, GetTLI, CG,
      DisableSampleProfileInlining, UseFlattenedProfile);
  if (!SampleLoader.doInitialization(M, &FAM))
    return PreservedAnalyses::all();

  ProfileSummaryInfo *PSI = &AM.getResult<ProfileSummaryAnalysis>(M);
  if (!SampleLoader.runOnModule(M, AM, PSI))
    return PreservedAnalyses::all();

  return PreservedAnalyses::none();
}
