//===- InstrProf.cpp - Instrumented profiling format support --------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains support for clang's instrumentation based PGO and
// coverage.
//
//===----------------------------------------------------------------------===//

#include "llvm/ProfileData/InstrProf.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Config/config.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/ProfileData/InstrProfReader.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Compression.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/SwapByteOrder.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/TargetParser/Triple.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <cstring>
#include <memory>
#include <string>
#include <system_error>
#include <type_traits>
#include <utility>
#include <vector>

using namespace llvm;

#define DEBUG_TYPE "instrprof"

static cl::opt<bool> StaticFuncFullModulePrefix(
    "static-func-full-module-prefix", cl::init(true), cl::Hidden,
    cl::desc("Use full module build paths in the profile counter names for "
             "static functions."));

// This option is tailored to users that have different top-level directory in
// profile-gen and profile-use compilation. Users need to specific the number
// of levels to strip. A value larger than the number of directories in the
// source file will strip all the directory names and only leave the basename.
//
// Note current ThinLTO module importing for the indirect-calls assumes
// the source directory name not being stripped. A non-zero option value here
// can potentially prevent some inter-module indirect-call-promotions.
static cl::opt<unsigned> StaticFuncStripDirNamePrefix(
    "static-func-strip-dirname-prefix", cl::init(0), cl::Hidden,
    cl::desc("Strip specified level of directory name from source path in "
             "the profile counter name for static functions."));

static std::string getInstrProfErrString(instrprof_error Err,
                                         const std::string &ErrMsg = "") {
  std::string Msg;
  raw_string_ostream OS(Msg);

  switch (Err) {
  case instrprof_error::success:
    OS << "success";
    break;
  case instrprof_error::eof:
    OS << "end of File";
    break;
  case instrprof_error::unrecognized_format:
    OS << "unrecognized instrumentation profile encoding format";
    break;
  case instrprof_error::bad_magic:
    OS << "invalid instrumentation profile data (bad magic)";
    break;
  case instrprof_error::bad_header:
    OS << "invalid instrumentation profile data (file header is corrupt)";
    break;
  case instrprof_error::unsupported_version:
    OS << "unsupported instrumentation profile format version";
    break;
  case instrprof_error::unsupported_hash_type:
    OS << "unsupported instrumentation profile hash type";
    break;
  case instrprof_error::too_large:
    OS << "too much profile data";
    break;
  case instrprof_error::truncated:
    OS << "truncated profile data";
    break;
  case instrprof_error::malformed:
    OS << "malformed instrumentation profile data";
    break;
  case instrprof_error::missing_correlation_info:
    OS << "debug info/binary for correlation is required";
    break;
  case instrprof_error::unexpected_correlation_info:
    OS << "debug info/binary for correlation is not necessary";
    break;
  case instrprof_error::unable_to_correlate_profile:
    OS << "unable to correlate profile";
    break;
  case instrprof_error::invalid_prof:
    OS << "invalid profile created. Please file a bug "
          "at: " BUG_REPORT_URL
          " and include the profraw files that caused this error.";
    break;
  case instrprof_error::unknown_function:
    OS << "no profile data available for function";
    break;
  case instrprof_error::hash_mismatch:
    OS << "function control flow change detected (hash mismatch)";
    break;
  case instrprof_error::count_mismatch:
    OS << "function basic block count change detected (counter mismatch)";
    break;
  case instrprof_error::bitmap_mismatch:
    OS << "function bitmap size change detected (bitmap size mismatch)";
    break;
  case instrprof_error::counter_overflow:
    OS << "counter overflow";
    break;
  case instrprof_error::value_site_count_mismatch:
    OS << "function value site count change detected (counter mismatch)";
    break;
  case instrprof_error::compress_failed:
    OS << "failed to compress data (zlib)";
    break;
  case instrprof_error::uncompress_failed:
    OS << "failed to uncompress data (zlib)";
    break;
  case instrprof_error::empty_raw_profile:
    OS << "empty raw profile file";
    break;
  case instrprof_error::zlib_unavailable:
    OS << "profile uses zlib compression but the profile reader was built "
          "without zlib support";
    break;
  case instrprof_error::raw_profile_version_mismatch:
    OS << "raw profile version mismatch";
    break;
  case instrprof_error::counter_value_too_large:
    OS << "excessively large counter value suggests corrupted profile data";
    break;
  }

  // If optional error message is not empty, append it to the message.
  if (!ErrMsg.empty())
    OS << ": " << ErrMsg;

  return OS.str();
}

namespace {

// FIXME: This class is only here to support the transition to llvm::Error. It
// will be removed once this transition is complete. Clients should prefer to
// deal with the Error value directly, rather than converting to error_code.
class InstrProfErrorCategoryType : public std::error_category {
  const char *name() const noexcept override { return "llvm.instrprof"; }

  std::string message(int IE) const override {
    return getInstrProfErrString(static_cast<instrprof_error>(IE));
  }
};

} // end anonymous namespace

const std::error_category &llvm::instrprof_category() {
  static InstrProfErrorCategoryType ErrorCategory;
  return ErrorCategory;
}

namespace {

const char *InstrProfSectNameCommon[] = {
#define INSTR_PROF_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix)      \
  SectNameCommon,
#include "llvm/ProfileData/InstrProfData.inc"
};

const char *InstrProfSectNameCoff[] = {
#define INSTR_PROF_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix)      \
  SectNameCoff,
#include "llvm/ProfileData/InstrProfData.inc"
};

const char *InstrProfSectNamePrefix[] = {
#define INSTR_PROF_SECT_ENTRY(Kind, SectNameCommon, SectNameCoff, Prefix)      \
  Prefix,
#include "llvm/ProfileData/InstrProfData.inc"
};

} // namespace

namespace llvm {

cl::opt<bool> DoInstrProfNameCompression(
    "enable-name-compression",
    cl::desc("Enable name/filename string compression"), cl::init(true));

cl::opt<bool> EnableVTableValueProfiling(
    "enable-vtable-value-profiling", cl::init(false),
    cl::desc("If true, the virtual table address will be instrumented to know "
             "the types of a C++ pointer. The information is used in indirect "
             "call promotion to do selective vtable-based comparison."));

cl::opt<bool> EnableVTableProfileUse(
    "enable-vtable-profile-use", cl::init(false),
    cl::desc("If ThinLTO and WPD is enabled and this option is true, vtable "
             "profiles will be used by ICP pass for more efficient indirect "
             "call sequence. If false, type profiles won't be used."));

std::string getInstrProfSectionName(InstrProfSectKind IPSK,
                                    Triple::ObjectFormatType OF,
                                    bool AddSegmentInfo) {
  std::string SectName;

  if (OF == Triple::MachO && AddSegmentInfo)
    SectName = InstrProfSectNamePrefix[IPSK];

  if (OF == Triple::COFF)
    SectName += InstrProfSectNameCoff[IPSK];
  else
    SectName += InstrProfSectNameCommon[IPSK];

  if (OF == Triple::MachO && IPSK == IPSK_data && AddSegmentInfo)
    SectName += ",regular,live_support";

  return SectName;
}

std::string InstrProfError::message() const {
  return getInstrProfErrString(Err, Msg);
}

char InstrProfError::ID = 0;

ProfOStream::ProfOStream(raw_fd_ostream &FD)
    : IsFDOStream(true), OS(FD), LE(FD, llvm::endianness::little) {}

ProfOStream::ProfOStream(raw_string_ostream &STR)
    : IsFDOStream(false), OS(STR), LE(STR, llvm::endianness::little) {}

uint64_t ProfOStream::tell() const { return OS.tell(); }
void ProfOStream::write(uint64_t V) { LE.write<uint64_t>(V); }
void ProfOStream::write32(uint32_t V) { LE.write<uint32_t>(V); }
void ProfOStream::writeByte(uint8_t V) { LE.write<uint8_t>(V); }

void ProfOStream::patch(ArrayRef<PatchItem> P) {
  using namespace support;

  if (IsFDOStream) {
    raw_fd_ostream &FDOStream = static_cast<raw_fd_ostream &>(OS);
    const uint64_t LastPos = FDOStream.tell();
    for (const auto &K : P) {
      FDOStream.seek(K.Pos);
      for (uint64_t Elem : K.D)
        write(Elem);
    }
    // Reset the stream to the last position after patching so that users
    // don't accidentally overwrite data. This makes it consistent with
    // the string stream below which replaces the data directly.
    FDOStream.seek(LastPos);
  } else {
    raw_string_ostream &SOStream = static_cast<raw_string_ostream &>(OS);
    std::string &Data = SOStream.str(); // with flush
    for (const auto &K : P) {
      for (int I = 0, E = K.D.size(); I != E; I++) {
        uint64_t Bytes =
            endian::byte_swap<uint64_t, llvm::endianness::little>(K.D[I]);
        Data.replace(K.Pos + I * sizeof(uint64_t), sizeof(uint64_t),
                     (const char *)&Bytes, sizeof(uint64_t));
      }
    }
  }
}

std::string getPGOFuncName(StringRef Name, GlobalValue::LinkageTypes Linkage,
                           StringRef FileName,
                           uint64_t Version LLVM_ATTRIBUTE_UNUSED) {
  // Value names may be prefixed with a binary '1' to indicate
  // that the backend should not modify the symbols due to any platform
  // naming convention. Do not include that '1' in the PGO profile name.
  if (Name[0] == '\1')
    Name = Name.substr(1);

  std::string NewName = std::string(Name);
  if (llvm::GlobalValue::isLocalLinkage(Linkage)) {
    // For local symbols, prepend the main file name to distinguish them.
    // Do not include the full path in the file name since there's no guarantee
    // that it will stay the same, e.g., if the files are checked out from
    // version control in different locations.
    if (FileName.empty())
      NewName = NewName.insert(0, "<unknown>:");
    else
      NewName = NewName.insert(0, FileName.str() + ":");
  }
  return NewName;
}

// Strip NumPrefix level of directory name from PathNameStr. If the number of
// directory separators is less than NumPrefix, strip all the directories and
// leave base file name only.
static StringRef stripDirPrefix(StringRef PathNameStr, uint32_t NumPrefix) {
  uint32_t Count = NumPrefix;
  uint32_t Pos = 0, LastPos = 0;
  for (const auto &CI : PathNameStr) {
    ++Pos;
    if (llvm::sys::path::is_separator(CI)) {
      LastPos = Pos;
      --Count;
    }
    if (Count == 0)
      break;
  }
  return PathNameStr.substr(LastPos);
}

static StringRef getStrippedSourceFileName(const GlobalObject &GO) {
  StringRef FileName(GO.getParent()->getSourceFileName());
  uint32_t StripLevel = StaticFuncFullModulePrefix ? 0 : (uint32_t)-1;
  if (StripLevel < StaticFuncStripDirNamePrefix)
    StripLevel = StaticFuncStripDirNamePrefix;
  if (StripLevel)
    FileName = stripDirPrefix(FileName, StripLevel);
  return FileName;
}

// The PGO name has the format [<filepath>;]<mangled-name> where <filepath>; is
// provided if linkage is local and is used to discriminate possibly identical
// mangled names. ";" is used because it is unlikely to be found in either
// <filepath> or <mangled-name>.
//
// Older compilers used getPGOFuncName() which has the format
// [<filepath>:]<mangled-name>. This caused trouble for Objective-C functions
// which commonly have :'s in their names. We still need to compute this name to
// lookup functions from profiles built by older compilers.
static std::string
getIRPGONameForGlobalObject(const GlobalObject &GO,
                            GlobalValue::LinkageTypes Linkage,
                            StringRef FileName) {
  return GlobalValue::getGlobalIdentifier(GO.getName(), Linkage, FileName);
}

static std::optional<std::string> lookupPGONameFromMetadata(MDNode *MD) {
  if (MD != nullptr) {
    StringRef S = cast<MDString>(MD->getOperand(0))->getString();
    return S.str();
  }
  return {};
}

// Returns the PGO object name. This function has some special handling
// when called in LTO optimization. The following only applies when calling in
// LTO passes (when \c InLTO is true): LTO's internalization privatizes many
// global linkage symbols. This happens after value profile annotation, but
// those internal linkage functions should not have a source prefix.
// Additionally, for ThinLTO mode, exported internal functions are promoted
// and renamed. We need to ensure that the original internal PGO name is
// used when computing the GUID that is compared against the profiled GUIDs.
// To differentiate compiler generated internal symbols from original ones,
// PGOFuncName meta data are created and attached to the original internal
// symbols in the value profile annotation step
// (PGOUseFunc::annotateIndirectCallSites). If a symbol does not have the meta
// data, its original linkage must be non-internal.
static std::string getIRPGOObjectName(const GlobalObject &GO, bool InLTO,
                                      MDNode *PGONameMetadata) {
  if (!InLTO) {
    auto FileName = getStrippedSourceFileName(GO);
    return getIRPGONameForGlobalObject(GO, GO.getLinkage(), FileName);
  }

  // In LTO mode (when InLTO is true), first check if there is a meta data.
  if (auto IRPGOFuncName = lookupPGONameFromMetadata(PGONameMetadata))
    return *IRPGOFuncName;

  // If there is no meta data, the function must be a global before the value
  // profile annotation pass. Its current linkage may be internal if it is
  // internalized in LTO mode.
  return getIRPGONameForGlobalObject(GO, GlobalValue::ExternalLinkage, "");
}

// Returns the IRPGO function name and does special handling when called
// in LTO optimization. See the comments of `getIRPGOObjectName` for details.
std::string getIRPGOFuncName(const Function &F, bool InLTO) {
  return getIRPGOObjectName(F, InLTO, getPGOFuncNameMetadata(F));
}

// Please use getIRPGOFuncName for LLVM IR instrumentation. This function is
// for front-end (Clang, etc) instrumentation.
// The implementation is kept for profile matching from older profiles.
// This is similar to `getIRPGOFuncName` except that this function calls
// 'getPGOFuncName' to get a name and `getIRPGOFuncName` calls
// 'getIRPGONameForGlobalObject'. See the difference between two callees in the
// comments of `getIRPGONameForGlobalObject`.
std::string getPGOFuncName(const Function &F, bool InLTO, uint64_t Version) {
  if (!InLTO) {
    auto FileName = getStrippedSourceFileName(F);
    return getPGOFuncName(F.getName(), F.getLinkage(), FileName, Version);
  }

  // In LTO mode (when InLTO is true), first check if there is a meta data.
  if (auto PGOFuncName = lookupPGONameFromMetadata(getPGOFuncNameMetadata(F)))
    return *PGOFuncName;

  // If there is no meta data, the function must be a global before the value
  // profile annotation pass. Its current linkage may be internal if it is
  // internalized in LTO mode.
  return getPGOFuncName(F.getName(), GlobalValue::ExternalLinkage, "");
}

std::string getPGOName(const GlobalVariable &V, bool InLTO) {
  // PGONameMetadata should be set by compiler at profile use time
  // and read by symtab creation to look up symbols corresponding to
  // a MD5 hash.
  return getIRPGOObjectName(V, InLTO, V.getMetadata(getPGONameMetadataName()));
}

// See getIRPGOObjectName() for a discription of the format.
std::pair<StringRef, StringRef> getParsedIRPGOName(StringRef IRPGOName) {
  auto [FileName, MangledName] = IRPGOName.split(GlobalIdentifierDelimiter);
  if (MangledName.empty())
    return std::make_pair(StringRef(), IRPGOName);
  return std::make_pair(FileName, MangledName);
}

StringRef getFuncNameWithoutPrefix(StringRef PGOFuncName, StringRef FileName) {
  if (FileName.empty())
    return PGOFuncName;
  // Drop the file name including ':' or ';'. See getIRPGONameForGlobalObject as
  // well.
  if (PGOFuncName.starts_with(FileName))
    PGOFuncName = PGOFuncName.drop_front(FileName.size() + 1);
  return PGOFuncName;
}

// \p FuncName is the string used as profile lookup key for the function. A
// symbol is created to hold the name. Return the legalized symbol name.
std::string getPGOFuncNameVarName(StringRef FuncName,
                                  GlobalValue::LinkageTypes Linkage) {
  std::string VarName = std::string(getInstrProfNameVarPrefix());
  VarName += FuncName;

  if (!GlobalValue::isLocalLinkage(Linkage))
    return VarName;

  // Now fix up illegal chars in local VarName that may upset the assembler.
  const char InvalidChars[] = "-:;<>/\"'";
  size_t FoundPos = VarName.find_first_of(InvalidChars);
  while (FoundPos != std::string::npos) {
    VarName[FoundPos] = '_';
    FoundPos = VarName.find_first_of(InvalidChars, FoundPos + 1);
  }
  return VarName;
}

bool isGPUProfTarget(const Module &M) {
  const Triple &T = M.getTargetTriple();
  return T.isGPU();
}

void setPGOFuncVisibility(Module &M, GlobalVariable *FuncNameVar) {
  // If the target is a GPU, make the symbol protected so it can
  // be read from the host device
  if (isGPUProfTarget(M))
    FuncNameVar->setVisibility(GlobalValue::ProtectedVisibility);
  // Hide the symbol so that we correctly get a copy for each executable.
  else if (!GlobalValue::isLocalLinkage(FuncNameVar->getLinkage()))
    FuncNameVar->setVisibility(GlobalValue::HiddenVisibility);
}

GlobalVariable *createPGOFuncNameVar(Module &M,
                                     GlobalValue::LinkageTypes Linkage,
                                     StringRef PGOFuncName) {
  // Ensure profiling variables on GPU are visible to be read from host
  if (isGPUProfTarget(M))
    Linkage = GlobalValue::ExternalLinkage;
  // We generally want to match the function's linkage, but available_externally
  // and extern_weak both have the wrong semantics, and anything that doesn't
  // need to link across compilation units doesn't need to be visible at all.
  else if (Linkage == GlobalValue::ExternalWeakLinkage)
    Linkage = GlobalValue::LinkOnceAnyLinkage;
  else if (Linkage == GlobalValue::AvailableExternallyLinkage)
    Linkage = GlobalValue::LinkOnceODRLinkage;
  else if (Linkage == GlobalValue::InternalLinkage ||
           Linkage == GlobalValue::ExternalLinkage)
    Linkage = GlobalValue::PrivateLinkage;

  auto *Value =
      ConstantDataArray::getString(M.getContext(), PGOFuncName, false);
  auto *FuncNameVar =
      new GlobalVariable(M, Value->getType(), true, Linkage, Value,
                         getPGOFuncNameVarName(PGOFuncName, Linkage));

  setPGOFuncVisibility(M, FuncNameVar);
  return FuncNameVar;
}

GlobalVariable *createPGOFuncNameVar(Function &F, StringRef PGOFuncName) {
  return createPGOFuncNameVar(*F.getParent(), F.getLinkage(), PGOFuncName);
}

Error InstrProfSymtab::create(Module &M, bool InLTO, bool AddCanonical) {
  for (Function &F : M) {
    // Function may not have a name: like using asm("") to overwrite the name.
    // Ignore in this case.
    if (!F.hasName())
      continue;
    if (Error E = addFuncWithName(F, getIRPGOFuncName(F, InLTO), AddCanonical))
      return E;
    // Also use getPGOFuncName() so that we can find records from older profiles
    if (Error E = addFuncWithName(F, getPGOFuncName(F, InLTO), AddCanonical))
      return E;
  }

  SmallVector<MDNode *, 2> Types;
  for (GlobalVariable &G : M.globals()) {
    if (!G.hasName() || !G.hasMetadata(LLVMContext::MD_type))
      continue;
    if (Error E = addVTableWithName(G, getPGOName(G, InLTO)))
      return E;
  }

  Sorted = false;
  finalizeSymtab();
  return Error::success();
}

Error InstrProfSymtab::addVTableWithName(GlobalVariable &VTable,
                                         StringRef VTablePGOName) {
  auto NameToGUIDMap = [&](StringRef Name) -> Error {
    if (Error E = addSymbolName(Name))
      return E;

    bool Inserted = true;
    std::tie(std::ignore, Inserted) =
        MD5VTableMap.try_emplace(GlobalValue::getGUID(Name), &VTable);
    if (!Inserted)
      LLVM_DEBUG(dbgs() << "GUID conflict within one module");
    return Error::success();
  };
  if (Error E = NameToGUIDMap(VTablePGOName))
    return E;

  StringRef CanonicalName = getCanonicalName(VTablePGOName);
  if (CanonicalName != VTablePGOName)
    return NameToGUIDMap(CanonicalName);

  return Error::success();
}

/// \c NameStrings is a string composed of one of more possibly encoded
/// sub-strings. The substrings are separated by 0 or more zero bytes. This
/// method decodes the string and calls `NameCallback` for each substring.
static Error
readAndDecodeStrings(StringRef NameStrings,
                     std::function<Error(StringRef)> NameCallback) {
  const uint8_t *P = NameStrings.bytes_begin();
  const uint8_t *EndP = NameStrings.bytes_end();
  while (P < EndP) {
    uint32_t N;
    uint64_t UncompressedSize = decodeULEB128(P, &N);
    P += N;
    uint64_t CompressedSize = decodeULEB128(P, &N);
    P += N;
    const bool IsCompressed = (CompressedSize != 0);
    SmallVector<uint8_t, 128> UncompressedNameStrings;
    StringRef NameStrings;
    if (IsCompressed) {
      if (!llvm::compression::zlib::isAvailable())
        return make_error<InstrProfError>(instrprof_error::zlib_unavailable);

      if (Error E = compression::zlib::decompress(ArrayRef(P, CompressedSize),
                                                  UncompressedNameStrings,
                                                  UncompressedSize)) {
        consumeError(std::move(E));
        return make_error<InstrProfError>(instrprof_error::uncompress_failed);
      }
      P += CompressedSize;
      NameStrings = toStringRef(UncompressedNameStrings);
    } else {
      NameStrings =
          StringRef(reinterpret_cast<const char *>(P), UncompressedSize);
      P += UncompressedSize;
    }
    // Now parse the name strings.
    SmallVector<StringRef, 0> Names;
    NameStrings.split(Names, getInstrProfNameSeparator());
    for (StringRef &Name : Names)
      if (Error E = NameCallback(Name))
        return E;

    while (P < EndP && *P == 0)
      P++;
  }
  return Error::success();
}

Error InstrProfSymtab::create(StringRef NameStrings) {
  return readAndDecodeStrings(
      NameStrings,
      std::bind(&InstrProfSymtab::addFuncName, this, std::placeholders::_1));
}

Error InstrProfSymtab::create(StringRef FuncNameStrings,
                              StringRef VTableNameStrings) {
  if (Error E = readAndDecodeStrings(FuncNameStrings,
                                     std::bind(&InstrProfSymtab::addFuncName,
                                               this, std::placeholders::_1)))
    return E;

  return readAndDecodeStrings(
      VTableNameStrings,
      std::bind(&InstrProfSymtab::addVTableName, this, std::placeholders::_1));
}

Error InstrProfSymtab::initVTableNamesFromCompressedStrings(
    StringRef CompressedVTableStrings) {
  return readAndDecodeStrings(
      CompressedVTableStrings,
      std::bind(&InstrProfSymtab::addVTableName, this, std::placeholders::_1));
}

StringRef InstrProfSymtab::getCanonicalName(StringRef PGOName) {
  // In ThinLTO, local function may have been promoted to global and have
  // suffix ".llvm." added to the function name. We need to add the
  // stripped function name to the symbol table so that we can find a match
  // from profile.
  //
  // ".__uniq." suffix is used to differentiate internal linkage functions in
  // different modules and should be kept. This is the only suffix with the
  // pattern ".xxx" which is kept before matching, other suffixes similar as
  // ".llvm." will be stripped.
  const std::string UniqSuffix = ".__uniq.";
  size_t Pos = PGOName.find(UniqSuffix);
  if (Pos != StringRef::npos)
    Pos += UniqSuffix.length();
  else
    Pos = 0;

  // Search '.' after ".__uniq." if ".__uniq." exists, otherwise search '.' from
  // the beginning.
  Pos = PGOName.find('.', Pos);
  if (Pos != StringRef::npos && Pos != 0)
    return PGOName.substr(0, Pos);

  return PGOName;
}

Error InstrProfSymtab::addFuncWithName(Function &F, StringRef PGOFuncName,
                                       bool AddCanonical) {
  auto NameToGUIDMap = [&](StringRef Name) -> Error {
    if (Error E = addFuncName(Name))
      return E;
    MD5FuncMap.emplace_back(Function::getGUID(Name), &F);
    return Error::success();
  };
  if (Error E = NameToGUIDMap(PGOFuncName))
    return E;

  if (!AddCanonical)
    return Error::success();

  StringRef CanonicalFuncName = getCanonicalName(PGOFuncName);
  if (CanonicalFuncName != PGOFuncName)
    return NameToGUIDMap(CanonicalFuncName);

  return Error::success();
}

uint64_t InstrProfSymtab::getVTableHashFromAddress(uint64_t Address) {
  // Given a runtime address, look up the hash value in the interval map, and
  // fallback to value 0 if a hash value is not found.
  return VTableAddrMap.lookup(Address, 0);
}

uint64_t InstrProfSymtab::getFunctionHashFromAddress(uint64_t Address) {
  finalizeSymtab();
  auto It = partition_point(AddrToMD5Map, [=](std::pair<uint64_t, uint64_t> A) {
    return A.first < Address;
  });
  // Raw function pointer collected by value profiler may be from
  // external functions that are not instrumented. They won't have
  // mapping data to be used by the deserializer. Force the value to
  // be 0 in this case.
  if (It != AddrToMD5Map.end() && It->first == Address)
    return (uint64_t)It->second;
  return 0;
}

void InstrProfSymtab::dumpNames(raw_ostream &OS) const {
  SmallVector<StringRef, 0> Sorted(NameTab.keys());
  llvm::sort(Sorted);
  for (StringRef S : Sorted)
    OS << S << '\n';
}

Error collectGlobalObjectNameStrings(ArrayRef<std::string> NameStrs,
                                     bool DoCompression, std::string &Result) {
  assert(!NameStrs.empty() && "No name data to emit");

  uint8_t Header[20], *P = Header;
  std::string UncompressedNameStrings =
      join(NameStrs.begin(), NameStrs.end(), getInstrProfNameSeparator());

  assert(StringRef(UncompressedNameStrings)
                 .count(getInstrProfNameSeparator()) == (NameStrs.size() - 1) &&
         "PGO name is invalid (contains separator token)");

  unsigned EncLen = encodeULEB128(UncompressedNameStrings.length(), P);
  P += EncLen;

  auto WriteStringToResult = [&](size_t CompressedLen, StringRef InputStr) {
    EncLen = encodeULEB128(CompressedLen, P);
    P += EncLen;
    char *HeaderStr = reinterpret_cast<char *>(&Header[0]);
    unsigned HeaderLen = P - &Header[0];
    Result.append(HeaderStr, HeaderLen);
    Result += InputStr;
    return Error::success();
  };

  if (!DoCompression) {
    return WriteStringToResult(0, UncompressedNameStrings);
  }

  SmallVector<uint8_t, 128> CompressedNameStrings;
  compression::zlib::compress(arrayRefFromStringRef(UncompressedNameStrings),
                              CompressedNameStrings,
                              compression::zlib::BestSizeCompression);

  return WriteStringToResult(CompressedNameStrings.size(),
                             toStringRef(CompressedNameStrings));
}

StringRef getPGOFuncNameVarInitializer(GlobalVariable *NameVar) {
  auto *Arr = cast<ConstantDataArray>(NameVar->getInitializer());
  StringRef NameStr =
      Arr->isCString() ? Arr->getAsCString() : Arr->getAsString();
  return NameStr;
}

Error collectPGOFuncNameStrings(ArrayRef<GlobalVariable *> NameVars,
                                std::string &Result, bool DoCompression) {
  std::vector<std::string> NameStrs;
  for (auto *NameVar : NameVars) {
    NameStrs.push_back(std::string(getPGOFuncNameVarInitializer(NameVar)));
  }
  return collectGlobalObjectNameStrings(
      NameStrs, compression::zlib::isAvailable() && DoCompression, Result);
}

Error collectVTableStrings(ArrayRef<GlobalVariable *> VTables,
                           std::string &Result, bool DoCompression) {
  std::vector<std::string> VTableNameStrs;
  for (auto *VTable : VTables)
    VTableNameStrs.push_back(getPGOName(*VTable));
  return collectGlobalObjectNameStrings(
      VTableNameStrs, compression::zlib::isAvailable() && DoCompression,
      Result);
}

void InstrProfRecord::accumulateCounts(CountSumOrPercent &Sum) const {
  uint64_t FuncSum = 0;
  Sum.NumEntries += Counts.size();
  for (uint64_t Count : Counts)
    FuncSum += Count;
  Sum.CountSum += FuncSum;

  for (uint32_t VK = IPVK_First; VK <= IPVK_Last; ++VK) {
    uint64_t KindSum = 0;
    uint32_t NumValueSites = getNumValueSites(VK);
    for (size_t I = 0; I < NumValueSites; ++I) {
      for (const auto &V : getValueArrayForSite(VK, I))
        KindSum += V.Count;
    }
    Sum.ValueCounts[VK] += KindSum;
  }
}

void InstrProfValueSiteRecord::overlap(InstrProfValueSiteRecord &Input,
                                       uint32_t ValueKind,
                                       OverlapStats &Overlap,
                                       OverlapStats &FuncLevelOverlap) {
  this->sortByTargetValues();
  Input.sortByTargetValues();
  double Score = 0.0f, FuncLevelScore = 0.0f;
  auto I = ValueData.begin();
  auto IE = ValueData.end();
  auto J = Input.ValueData.begin();
  auto JE = Input.ValueData.end();
  while (I != IE && J != JE) {
    if (I->Value == J->Value) {
      Score += OverlapStats::score(I->Count, J->Count,
                                   Overlap.Base.ValueCounts[ValueKind],
                                   Overlap.Test.ValueCounts[ValueKind]);
      FuncLevelScore += OverlapStats::score(
          I->Count, J->Count, FuncLevelOverlap.Base.ValueCounts[ValueKind],
          FuncLevelOverlap.Test.ValueCounts[ValueKind]);
      ++I;
    } else if (I->Value < J->Value) {
      ++I;
      continue;
    }
    ++J;
  }
  Overlap.Overlap.ValueCounts[ValueKind] += Score;
  FuncLevelOverlap.Overlap.ValueCounts[ValueKind] += FuncLevelScore;
}

// Return false on mismatch.
void InstrProfRecord::overlapValueProfData(uint32_t ValueKind,
                                           InstrProfRecord &Other,
                                           OverlapStats &Overlap,
                                           OverlapStats &FuncLevelOverlap) {
  uint32_t ThisNumValueSites = getNumValueSites(ValueKind);
  assert(ThisNumValueSites == Other.getNumValueSites(ValueKind));
  if (!ThisNumValueSites)
    return;

  std::vector<InstrProfValueSiteRecord> &ThisSiteRecords =
      getOrCreateValueSitesForKind(ValueKind);
  MutableArrayRef<InstrProfValueSiteRecord> OtherSiteRecords =
      Other.getValueSitesForKind(ValueKind);
  for (uint32_t I = 0; I < ThisNumValueSites; I++)
    ThisSiteRecords[I].overlap(OtherSiteRecords[I], ValueKind, Overlap,
                               FuncLevelOverlap);
}

void InstrProfRecord::overlap(InstrProfRecord &Other, OverlapStats &Overlap,
                              OverlapStats &FuncLevelOverlap,
                              uint64_t ValueCutoff) {
  // FuncLevel CountSum for other should already computed and nonzero.
  assert(FuncLevelOverlap.Test.CountSum >= 1.0f);
  accumulateCounts(FuncLevelOverlap.Base);
  bool Mismatch = (Counts.size() != Other.Counts.size());

  // Check if the value profiles mismatch.
  if (!Mismatch) {
    for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) {
      uint32_t ThisNumValueSites = getNumValueSites(Kind);
      uint32_t OtherNumValueSites = Other.getNumValueSites(Kind);
      if (ThisNumValueSites != OtherNumValueSites) {
        Mismatch = true;
        break;
      }
    }
  }
  if (Mismatch) {
    Overlap.addOneMismatch(FuncLevelOverlap.Test);
    return;
  }

  // Compute overlap for value counts.
  for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind)
    overlapValueProfData(Kind, Other, Overlap, FuncLevelOverlap);

  double Score = 0.0;
  uint64_t MaxCount = 0;
  // Compute overlap for edge counts.
  for (size_t I = 0, E = Other.Counts.size(); I < E; ++I) {
    Score += OverlapStats::score(Counts[I], Other.Counts[I],
                                 Overlap.Base.CountSum, Overlap.Test.CountSum);
    MaxCount = std::max(Other.Counts[I], MaxCount);
  }
  Overlap.Overlap.CountSum += Score;
  Overlap.Overlap.NumEntries += 1;

  if (MaxCount >= ValueCutoff) {
    double FuncScore = 0.0;
    for (size_t I = 0, E = Other.Counts.size(); I < E; ++I)
      FuncScore += OverlapStats::score(Counts[I], Other.Counts[I],
                                       FuncLevelOverlap.Base.CountSum,
                                       FuncLevelOverlap.Test.CountSum);
    FuncLevelOverlap.Overlap.CountSum = FuncScore;
    FuncLevelOverlap.Overlap.NumEntries = Other.Counts.size();
    FuncLevelOverlap.Valid = true;
  }
}

void InstrProfValueSiteRecord::merge(InstrProfValueSiteRecord &Input,
                                     uint64_t Weight,
                                     function_ref<void(instrprof_error)> Warn) {
  this->sortByTargetValues();
  Input.sortByTargetValues();
  auto I = ValueData.begin();
  auto IE = ValueData.end();
  std::vector<InstrProfValueData> Merged;
  Merged.reserve(std::max(ValueData.size(), Input.ValueData.size()));
  for (const InstrProfValueData &J : Input.ValueData) {
    while (I != IE && I->Value < J.Value) {
      Merged.push_back(*I);
      ++I;
    }
    if (I != IE && I->Value == J.Value) {
      bool Overflowed;
      I->Count = SaturatingMultiplyAdd(J.Count, Weight, I->Count, &Overflowed);
      if (Overflowed)
        Warn(instrprof_error::counter_overflow);
      Merged.push_back(*I);
      ++I;
      continue;
    }
    Merged.push_back(J);
  }
  Merged.insert(Merged.end(), I, IE);
  ValueData = std::move(Merged);
}

void InstrProfValueSiteRecord::scale(uint64_t N, uint64_t D,
                                     function_ref<void(instrprof_error)> Warn) {
  for (InstrProfValueData &I : ValueData) {
    bool Overflowed;
    I.Count = SaturatingMultiply(I.Count, N, &Overflowed) / D;
    if (Overflowed)
      Warn(instrprof_error::counter_overflow);
  }
}

// Merge Value Profile data from Src record to this record for ValueKind.
// Scale merged value counts by \p Weight.
void InstrProfRecord::mergeValueProfData(
    uint32_t ValueKind, InstrProfRecord &Src, uint64_t Weight,
    function_ref<void(instrprof_error)> Warn) {
  uint32_t ThisNumValueSites = getNumValueSites(ValueKind);
  uint32_t OtherNumValueSites = Src.getNumValueSites(ValueKind);
  if (ThisNumValueSites != OtherNumValueSites) {
    Warn(instrprof_error::value_site_count_mismatch);
    return;
  }
  if (!ThisNumValueSites)
    return;
  std::vector<InstrProfValueSiteRecord> &ThisSiteRecords =
      getOrCreateValueSitesForKind(ValueKind);
  MutableArrayRef<InstrProfValueSiteRecord> OtherSiteRecords =
      Src.getValueSitesForKind(ValueKind);
  for (uint32_t I = 0; I < ThisNumValueSites; I++)
    ThisSiteRecords[I].merge(OtherSiteRecords[I], Weight, Warn);
}

void InstrProfRecord::merge(InstrProfRecord &Other, uint64_t Weight,
                            function_ref<void(instrprof_error)> Warn) {
  // If the number of counters doesn't match we either have bad data
  // or a hash collision.
  if (Counts.size() != Other.Counts.size()) {
    Warn(instrprof_error::count_mismatch);
    return;
  }

  // Special handling of the first count as the PseudoCount.
  CountPseudoKind OtherKind = Other.getCountPseudoKind();
  CountPseudoKind ThisKind = getCountPseudoKind();
  if (OtherKind != NotPseudo || ThisKind != NotPseudo) {
    // We don't allow the merge of a profile with pseudo counts and
    // a normal profile (i.e. without pesudo counts).
    // Profile supplimenation should be done after the profile merge.
    if (OtherKind == NotPseudo || ThisKind == NotPseudo) {
      Warn(instrprof_error::count_mismatch);
      return;
    }
    if (OtherKind == PseudoHot || ThisKind == PseudoHot)
      setPseudoCount(PseudoHot);
    else
      setPseudoCount(PseudoWarm);
    return;
  }

  for (size_t I = 0, E = Other.Counts.size(); I < E; ++I) {
    bool Overflowed;
    uint64_t Value =
        SaturatingMultiplyAdd(Other.Counts[I], Weight, Counts[I], &Overflowed);
    if (Value > getInstrMaxCountValue()) {
      Value = getInstrMaxCountValue();
      Overflowed = true;
    }
    Counts[I] = Value;
    if (Overflowed)
      Warn(instrprof_error::counter_overflow);
  }

  // If the number of bitmap bytes doesn't match we either have bad data
  // or a hash collision.
  if (BitmapBytes.size() != Other.BitmapBytes.size()) {
    Warn(instrprof_error::bitmap_mismatch);
    return;
  }

  // Bitmap bytes are merged by simply ORing them together.
  for (size_t I = 0, E = Other.BitmapBytes.size(); I < E; ++I) {
    BitmapBytes[I] = Other.BitmapBytes[I] | BitmapBytes[I];
  }

  for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind)
    mergeValueProfData(Kind, Other, Weight, Warn);
}

void InstrProfRecord::scaleValueProfData(
    uint32_t ValueKind, uint64_t N, uint64_t D,
    function_ref<void(instrprof_error)> Warn) {
  for (auto &R : getValueSitesForKind(ValueKind))
    R.scale(N, D, Warn);
}

void InstrProfRecord::scale(uint64_t N, uint64_t D,
                            function_ref<void(instrprof_error)> Warn) {
  assert(D != 0 && "D cannot be 0");
  for (auto &Count : this->Counts) {
    bool Overflowed;
    Count = SaturatingMultiply(Count, N, &Overflowed) / D;
    if (Count > getInstrMaxCountValue()) {
      Count = getInstrMaxCountValue();
      Overflowed = true;
    }
    if (Overflowed)
      Warn(instrprof_error::counter_overflow);
  }
  for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind)
    scaleValueProfData(Kind, N, D, Warn);
}

// Map indirect call target name hash to name string.
uint64_t InstrProfRecord::remapValue(uint64_t Value, uint32_t ValueKind,
                                     InstrProfSymtab *SymTab) {
  if (!SymTab)
    return Value;

  if (ValueKind == IPVK_IndirectCallTarget)
    return SymTab->getFunctionHashFromAddress(Value);

  if (ValueKind == IPVK_VTableTarget)
    return SymTab->getVTableHashFromAddress(Value);

  return Value;
}

void InstrProfRecord::addValueData(uint32_t ValueKind, uint32_t Site,
                                   ArrayRef<InstrProfValueData> VData,
                                   InstrProfSymtab *ValueMap) {
  // Remap values.
  std::vector<InstrProfValueData> RemappedVD;
  RemappedVD.reserve(VData.size());
  for (const auto &V : VData) {
    uint64_t NewValue = remapValue(V.Value, ValueKind, ValueMap);
    RemappedVD.push_back({NewValue, V.Count});
  }

  std::vector<InstrProfValueSiteRecord> &ValueSites =
      getOrCreateValueSitesForKind(ValueKind);
  assert(ValueSites.size() == Site);

  // Add a new value site with remapped value profiling data.
  ValueSites.emplace_back(std::move(RemappedVD));
}

void TemporalProfTraceTy::createBPFunctionNodes(
    ArrayRef<TemporalProfTraceTy> Traces, std::vector<BPFunctionNode> &Nodes,
    bool RemoveOutlierUNs) {
  using IDT = BPFunctionNode::IDT;
  using UtilityNodeT = BPFunctionNode::UtilityNodeT;
  UtilityNodeT MaxUN = 0;
  DenseMap<IDT, size_t> IdToFirstTimestamp;
  DenseMap<IDT, UtilityNodeT> IdToFirstUN;
  DenseMap<IDT, SmallVector<UtilityNodeT>> IdToUNs;
  // TODO: We need to use the Trace.Weight field to give more weight to more
  // important utilities
  for (auto &Trace : Traces) {
    size_t CutoffTimestamp = 1;
    for (size_t Timestamp = 0; Timestamp < Trace.FunctionNameRefs.size();
         Timestamp++) {
      IDT Id = Trace.FunctionNameRefs[Timestamp];
      auto [It, WasInserted] = IdToFirstTimestamp.try_emplace(Id, Timestamp);
      if (!WasInserted)
        It->getSecond() = std::min<size_t>(It->getSecond(), Timestamp);
      if (Timestamp >= CutoffTimestamp) {
        ++MaxUN;
        CutoffTimestamp = 2 * Timestamp;
      }
      IdToFirstUN.try_emplace(Id, MaxUN);
    }
    for (auto &[Id, FirstUN] : IdToFirstUN)
      for (auto UN = FirstUN; UN <= MaxUN; ++UN)
        IdToUNs[Id].push_back(UN);
    ++MaxUN;
    IdToFirstUN.clear();
  }

  if (RemoveOutlierUNs) {
    DenseMap<UtilityNodeT, unsigned> UNFrequency;
    for (auto &[Id, UNs] : IdToUNs)
      for (auto &UN : UNs)
        ++UNFrequency[UN];
    // Filter out utility nodes that are too infrequent or too prevalent to make
    // BalancedPartitioning more effective.
    for (auto &[Id, UNs] : IdToUNs)
      llvm::erase_if(UNs, [&](auto &UN) {
        unsigned Freq = UNFrequency[UN];
        return Freq <= 1 || 2 * Freq > IdToUNs.size();
      });
  }

  for (auto &[Id, UNs] : IdToUNs)
    Nodes.emplace_back(Id, UNs);

  // Since BalancedPartitioning is sensitive to the initial order, we explicitly
  // order nodes by their earliest timestamp.
  llvm::sort(Nodes, [&](auto &L, auto &R) {
    return std::make_pair(IdToFirstTimestamp[L.Id], L.Id) <
           std::make_pair(IdToFirstTimestamp[R.Id], R.Id);
  });
}

#define INSTR_PROF_COMMON_API_IMPL
#include "llvm/ProfileData/InstrProfData.inc"

/*!
 * ValueProfRecordClosure Interface implementation for  InstrProfRecord
 *  class. These C wrappers are used as adaptors so that C++ code can be
 *  invoked as callbacks.
 */
uint32_t getNumValueKindsInstrProf(const void *Record) {
  return reinterpret_cast<const InstrProfRecord *>(Record)->getNumValueKinds();
}

uint32_t getNumValueSitesInstrProf(const void *Record, uint32_t VKind) {
  return reinterpret_cast<const InstrProfRecord *>(Record)
      ->getNumValueSites(VKind);
}

uint32_t getNumValueDataInstrProf(const void *Record, uint32_t VKind) {
  return reinterpret_cast<const InstrProfRecord *>(Record)
      ->getNumValueData(VKind);
}

uint32_t getNumValueDataForSiteInstrProf(const void *R, uint32_t VK,
                                         uint32_t S) {
  const auto *IPR = reinterpret_cast<const InstrProfRecord *>(R);
  return IPR->getValueArrayForSite(VK, S).size();
}

void getValueForSiteInstrProf(const void *R, InstrProfValueData *Dst,
                              uint32_t K, uint32_t S) {
  const auto *IPR = reinterpret_cast<const InstrProfRecord *>(R);
  llvm::copy(IPR->getValueArrayForSite(K, S), Dst);
}

ValueProfData *allocValueProfDataInstrProf(size_t TotalSizeInBytes) {
  ValueProfData *VD =
      (ValueProfData *)(new (::operator new(TotalSizeInBytes)) ValueProfData());
  memset(VD, 0, TotalSizeInBytes);
  return VD;
}

static ValueProfRecordClosure InstrProfRecordClosure = {
    nullptr,
    getNumValueKindsInstrProf,
    getNumValueSitesInstrProf,
    getNumValueDataInstrProf,
    getNumValueDataForSiteInstrProf,
    nullptr,
    getValueForSiteInstrProf,
    allocValueProfDataInstrProf};

// Wrapper implementation using the closure mechanism.
uint32_t ValueProfData::getSize(const InstrProfRecord &Record) {
  auto Closure = InstrProfRecordClosure;
  Closure.Record = &Record;
  return getValueProfDataSize(&Closure);
}

// Wrapper implementation using the closure mechanism.
std::unique_ptr<ValueProfData>
ValueProfData::serializeFrom(const InstrProfRecord &Record) {
  InstrProfRecordClosure.Record = &Record;

  std::unique_ptr<ValueProfData> VPD(
      serializeValueProfDataFrom(&InstrProfRecordClosure, nullptr));
  return VPD;
}

void ValueProfRecord::deserializeTo(InstrProfRecord &Record,
                                    InstrProfSymtab *SymTab) {
  Record.reserveSites(Kind, NumValueSites);

  InstrProfValueData *ValueData = getValueProfRecordValueData(this);
  for (uint64_t VSite = 0; VSite < NumValueSites; ++VSite) {
    uint8_t ValueDataCount = this->SiteCountArray[VSite];
    ArrayRef<InstrProfValueData> VDs(ValueData, ValueDataCount);
    Record.addValueData(Kind, VSite, VDs, SymTab);
    ValueData += ValueDataCount;
  }
}

// For writing/serializing,  Old is the host endianness, and  New is
// byte order intended on disk. For Reading/deserialization, Old
// is the on-disk source endianness, and New is the host endianness.
void ValueProfRecord::swapBytes(llvm::endianness Old, llvm::endianness New) {
  using namespace support;

  if (Old == New)
    return;

  if (llvm::endianness::native != Old) {
    sys::swapByteOrder<uint32_t>(NumValueSites);
    sys::swapByteOrder<uint32_t>(Kind);
  }
  uint32_t ND = getValueProfRecordNumValueData(this);
  InstrProfValueData *VD = getValueProfRecordValueData(this);

  // No need to swap byte array: SiteCountArrray.
  for (uint32_t I = 0; I < ND; I++) {
    sys::swapByteOrder<uint64_t>(VD[I].Value);
    sys::swapByteOrder<uint64_t>(VD[I].Count);
  }
  if (llvm::endianness::native == Old) {
    sys::swapByteOrder<uint32_t>(NumValueSites);
    sys::swapByteOrder<uint32_t>(Kind);
  }
}

void ValueProfData::deserializeTo(InstrProfRecord &Record,
                                  InstrProfSymtab *SymTab) {
  if (NumValueKinds == 0)
    return;

  ValueProfRecord *VR = getFirstValueProfRecord(this);
  for (uint32_t K = 0; K < NumValueKinds; K++) {
    VR->deserializeTo(Record, SymTab);
    VR = getValueProfRecordNext(VR);
  }
}

static std::unique_ptr<ValueProfData> allocValueProfData(uint32_t TotalSize) {
  return std::unique_ptr<ValueProfData>(new (::operator new(TotalSize))
                                            ValueProfData());
}

Error ValueProfData::checkIntegrity() {
  if (NumValueKinds > IPVK_Last + 1)
    return make_error<InstrProfError>(
        instrprof_error::malformed, "number of value profile kinds is invalid");
  // Total size needs to be multiple of quadword size.
  if (TotalSize % sizeof(uint64_t))
    return make_error<InstrProfError>(
        instrprof_error::malformed, "total size is not multiples of quardword");

  ValueProfRecord *VR = getFirstValueProfRecord(this);
  for (uint32_t K = 0; K < this->NumValueKinds; K++) {
    if (VR->Kind > IPVK_Last)
      return make_error<InstrProfError>(instrprof_error::malformed,
                                        "value kind is invalid");
    VR = getValueProfRecordNext(VR);
    if ((char *)VR - (char *)this > (ptrdiff_t)TotalSize)
      return make_error<InstrProfError>(
          instrprof_error::malformed,
          "value profile address is greater than total size");
  }
  return Error::success();
}

Expected<std::unique_ptr<ValueProfData>>
ValueProfData::getValueProfData(const unsigned char *D,
                                const unsigned char *const BufferEnd,
                                llvm::endianness Endianness) {
  using namespace support;

  if (D + sizeof(ValueProfData) > BufferEnd)
    return make_error<InstrProfError>(instrprof_error::truncated);

  const unsigned char *Header = D;
  uint32_t TotalSize = endian::readNext<uint32_t>(Header, Endianness);

  if (D + TotalSize > BufferEnd)
    return make_error<InstrProfError>(instrprof_error::too_large);

  std::unique_ptr<ValueProfData> VPD = allocValueProfData(TotalSize);
  memcpy(VPD.get(), D, TotalSize);
  // Byte swap.
  VPD->swapBytesToHost(Endianness);

  Error E = VPD->checkIntegrity();
  if (E)
    return std::move(E);

  return std::move(VPD);
}

void ValueProfData::swapBytesToHost(llvm::endianness Endianness) {
  using namespace support;

  if (Endianness == llvm::endianness::native)
    return;

  sys::swapByteOrder<uint32_t>(TotalSize);
  sys::swapByteOrder<uint32_t>(NumValueKinds);

  ValueProfRecord *VR = getFirstValueProfRecord(this);
  for (uint32_t K = 0; K < NumValueKinds; K++) {
    VR->swapBytes(Endianness, llvm::endianness::native);
    VR = getValueProfRecordNext(VR);
  }
}

void ValueProfData::swapBytesFromHost(llvm::endianness Endianness) {
  using namespace support;

  if (Endianness == llvm::endianness::native)
    return;

  ValueProfRecord *VR = getFirstValueProfRecord(this);
  for (uint32_t K = 0; K < NumValueKinds; K++) {
    ValueProfRecord *NVR = getValueProfRecordNext(VR);
    VR->swapBytes(llvm::endianness::native, Endianness);
    VR = NVR;
  }
  sys::swapByteOrder<uint32_t>(TotalSize);
  sys::swapByteOrder<uint32_t>(NumValueKinds);
}

void annotateValueSite(Module &M, Instruction &Inst,
                       const InstrProfRecord &InstrProfR,
                       InstrProfValueKind ValueKind, uint32_t SiteIdx,
                       uint32_t MaxMDCount) {
  auto VDs = InstrProfR.getValueArrayForSite(ValueKind, SiteIdx);
  if (VDs.empty())
    return;
  uint64_t Sum = 0;
  for (const InstrProfValueData &V : VDs)
    Sum = SaturatingAdd(Sum, V.Count);
  annotateValueSite(M, Inst, VDs, Sum, ValueKind, MaxMDCount);
}

void annotateValueSite(Module &M, Instruction &Inst,
                       ArrayRef<InstrProfValueData> VDs,
                       uint64_t Sum, InstrProfValueKind ValueKind,
                       uint32_t MaxMDCount) {
  if (VDs.empty())
    return;
  LLVMContext &Ctx = M.getContext();
  MDBuilder MDHelper(Ctx);
  SmallVector<Metadata *, 3> Vals;
  // Tag
  Vals.push_back(MDHelper.createString("VP"));
  // Value Kind
  Vals.push_back(MDHelper.createConstant(
      ConstantInt::get(Type::getInt32Ty(Ctx), ValueKind)));
  // Total Count
  Vals.push_back(
      MDHelper.createConstant(ConstantInt::get(Type::getInt64Ty(Ctx), Sum)));

  // Value Profile Data
  uint32_t MDCount = MaxMDCount;
  for (const auto &VD : VDs) {
    Vals.push_back(MDHelper.createConstant(
        ConstantInt::get(Type::getInt64Ty(Ctx), VD.Value)));
    Vals.push_back(MDHelper.createConstant(
        ConstantInt::get(Type::getInt64Ty(Ctx), VD.Count)));
    if (--MDCount == 0)
      break;
  }
  Inst.setMetadata(LLVMContext::MD_prof, MDNode::get(Ctx, Vals));
}

MDNode *mayHaveValueProfileOfKind(const Instruction &Inst,
                                  InstrProfValueKind ValueKind) {
  MDNode *MD = Inst.getMetadata(LLVMContext::MD_prof);
  if (!MD)
    return nullptr;

  if (MD->getNumOperands() < 5)
    return nullptr;

  MDString *Tag = cast<MDString>(MD->getOperand(0));
  if (!Tag || Tag->getString() != "VP")
    return nullptr;

  // Now check kind:
  ConstantInt *KindInt = mdconst::dyn_extract<ConstantInt>(MD->getOperand(1));
  if (!KindInt)
    return nullptr;
  if (KindInt->getZExtValue() != ValueKind)
    return nullptr;

  return MD;
}

SmallVector<InstrProfValueData, 4>
getValueProfDataFromInst(const Instruction &Inst, InstrProfValueKind ValueKind,
                         uint32_t MaxNumValueData, uint64_t &TotalC,
                         bool GetNoICPValue) {
  // Four inline elements seem to work well in practice.  With MaxNumValueData,
  // this array won't grow very big anyway.
  SmallVector<InstrProfValueData, 4> ValueData;
  MDNode *MD = mayHaveValueProfileOfKind(Inst, ValueKind);
  if (!MD)
    return ValueData;
  const unsigned NOps = MD->getNumOperands();
  // Get total count
  ConstantInt *TotalCInt = mdconst::dyn_extract<ConstantInt>(MD->getOperand(2));
  if (!TotalCInt)
    return ValueData;
  TotalC = TotalCInt->getZExtValue();

  ValueData.reserve((NOps - 3) / 2);
  for (unsigned I = 3; I < NOps; I += 2) {
    if (ValueData.size() >= MaxNumValueData)
      break;
    ConstantInt *Value = mdconst::dyn_extract<ConstantInt>(MD->getOperand(I));
    ConstantInt *Count =
        mdconst::dyn_extract<ConstantInt>(MD->getOperand(I + 1));
    if (!Value || !Count) {
      ValueData.clear();
      return ValueData;
    }
    uint64_t CntValue = Count->getZExtValue();
    if (!GetNoICPValue && (CntValue == NOMORE_ICP_MAGICNUM))
      continue;
    InstrProfValueData V;
    V.Value = Value->getZExtValue();
    V.Count = CntValue;
    ValueData.push_back(V);
  }
  return ValueData;
}

MDNode *getPGOFuncNameMetadata(const Function &F) {
  return F.getMetadata(getPGOFuncNameMetadataName());
}

static void createPGONameMetadata(GlobalObject &GO, StringRef MetadataName,
                                  StringRef PGOName) {
  // Only for internal linkage functions or global variables. The name is not
  // the same as PGO name for these global objects.
  if (GO.getName() == PGOName)
    return;

  // Don't create duplicated metadata.
  if (GO.getMetadata(MetadataName))
    return;

  LLVMContext &C = GO.getContext();
  MDNode *N = MDNode::get(C, MDString::get(C, PGOName));
  GO.setMetadata(MetadataName, N);
}

void createPGOFuncNameMetadata(Function &F, StringRef PGOFuncName) {
  return createPGONameMetadata(F, getPGOFuncNameMetadataName(), PGOFuncName);
}

void createPGONameMetadata(GlobalObject &GO, StringRef PGOName) {
  return createPGONameMetadata(GO, getPGONameMetadataName(), PGOName);
}

bool needsComdatForCounter(const GlobalObject &GO, const Module &M) {
  if (GO.hasComdat())
    return true;

  if (!M.getTargetTriple().supportsCOMDAT())
    return false;

  // See createPGOFuncNameVar for more details. To avoid link errors, profile
  // counters for function with available_externally linkage needs to be changed
  // to linkonce linkage. On ELF based systems, this leads to weak symbols to be
  // created. Without using comdat, duplicate entries won't be removed by the
  // linker leading to increased data segement size and raw profile size. Even
  // worse, since the referenced counter from profile per-function data object
  // will be resolved to the common strong definition, the profile counts for
  // available_externally functions will end up being duplicated in raw profile
  // data. This can result in distorted profile as the counts of those dups
  // will be accumulated by the profile merger.
  GlobalValue::LinkageTypes Linkage = GO.getLinkage();
  if (Linkage != GlobalValue::ExternalWeakLinkage &&
      Linkage != GlobalValue::AvailableExternallyLinkage)
    return false;

  return true;
}

// Check if INSTR_PROF_RAW_VERSION_VAR is defined.
bool isIRPGOFlagSet(const Module *M) {
  const GlobalVariable *IRInstrVar =
      M->getNamedGlobal(INSTR_PROF_QUOTE(INSTR_PROF_RAW_VERSION_VAR));
  if (!IRInstrVar || IRInstrVar->hasLocalLinkage())
    return false;

  // For CSPGO+LTO, this variable might be marked as non-prevailing and we only
  // have the decl.
  if (IRInstrVar->isDeclaration())
    return true;

  // Check if the flag is set.
  if (!IRInstrVar->hasInitializer())
    return false;

  auto *InitVal = dyn_cast_or_null<ConstantInt>(IRInstrVar->getInitializer());
  if (!InitVal)
    return false;
  return (InitVal->getZExtValue() & VARIANT_MASK_IR_PROF) != 0;
}

// Check if we can safely rename this Comdat function.
bool canRenameComdatFunc(const Function &F, bool CheckAddressTaken) {
  if (F.getName().empty())
    return false;
  if (!needsComdatForCounter(F, *(F.getParent())))
    return false;
  // Unsafe to rename the address-taken function (which can be used in
  // function comparison).
  if (CheckAddressTaken && F.hasAddressTaken())
    return false;
  // Only safe to do if this function may be discarded if it is not used
  // in the compilation unit.
  if (!GlobalValue::isDiscardableIfUnused(F.getLinkage()))
    return false;

  // For AvailableExternallyLinkage functions.
  if (!F.hasComdat()) {
    assert(F.getLinkage() == GlobalValue::AvailableExternallyLinkage);
    return true;
  }
  return true;
}

// Create the variable for the profile file name.
void createProfileFileNameVar(Module &M, StringRef InstrProfileOutput) {
  if (InstrProfileOutput.empty())
    return;
  Constant *ProfileNameConst =
      ConstantDataArray::getString(M.getContext(), InstrProfileOutput, true);
  GlobalVariable *ProfileNameVar = new GlobalVariable(
      M, ProfileNameConst->getType(), true, GlobalValue::WeakAnyLinkage,
      ProfileNameConst, INSTR_PROF_QUOTE(INSTR_PROF_PROFILE_NAME_VAR));
  ProfileNameVar->setVisibility(GlobalValue::HiddenVisibility);
  Triple TT(M.getTargetTriple());
  if (TT.supportsCOMDAT()) {
    ProfileNameVar->setLinkage(GlobalValue::ExternalLinkage);
    ProfileNameVar->setComdat(M.getOrInsertComdat(
        StringRef(INSTR_PROF_QUOTE(INSTR_PROF_PROFILE_NAME_VAR))));
  }
}

Error OverlapStats::accumulateCounts(const std::string &BaseFilename,
                                     const std::string &TestFilename,
                                     bool IsCS) {
  auto GetProfileSum = [IsCS](const std::string &Filename,
                              CountSumOrPercent &Sum) -> Error {
    // This function is only used from llvm-profdata that doesn't use any kind
    // of VFS. Just create a default RealFileSystem to read profiles.
    auto FS = vfs::getRealFileSystem();
    auto ReaderOrErr = InstrProfReader::create(Filename, *FS);
    if (Error E = ReaderOrErr.takeError()) {
      return E;
    }
    auto Reader = std::move(ReaderOrErr.get());
    Reader->accumulateCounts(Sum, IsCS);
    return Error::success();
  };
  auto Ret = GetProfileSum(BaseFilename, Base);
  if (Ret)
    return Ret;
  Ret = GetProfileSum(TestFilename, Test);
  if (Ret)
    return Ret;
  this->BaseFilename = &BaseFilename;
  this->TestFilename = &TestFilename;
  Valid = true;
  return Error::success();
}

void OverlapStats::addOneMismatch(const CountSumOrPercent &MismatchFunc) {
  Mismatch.NumEntries += 1;
  Mismatch.CountSum += MismatchFunc.CountSum / Test.CountSum;
  for (unsigned I = 0; I < IPVK_Last - IPVK_First + 1; I++) {
    if (Test.ValueCounts[I] >= 1.0f)
      Mismatch.ValueCounts[I] +=
          MismatchFunc.ValueCounts[I] / Test.ValueCounts[I];
  }
}

void OverlapStats::addOneUnique(const CountSumOrPercent &UniqueFunc) {
  Unique.NumEntries += 1;
  Unique.CountSum += UniqueFunc.CountSum / Test.CountSum;
  for (unsigned I = 0; I < IPVK_Last - IPVK_First + 1; I++) {
    if (Test.ValueCounts[I] >= 1.0f)
      Unique.ValueCounts[I] += UniqueFunc.ValueCounts[I] / Test.ValueCounts[I];
  }
}

void OverlapStats::dump(raw_fd_ostream &OS) const {
  if (!Valid)
    return;

  const char *EntryName =
      (Level == ProgramLevel ? "functions" : "edge counters");
  if (Level == ProgramLevel) {
    OS << "Profile overlap infomation for base_profile: " << *BaseFilename
       << " and test_profile: " << *TestFilename << "\nProgram level:\n";
  } else {
    OS << "Function level:\n"
       << "  Function: " << FuncName << " (Hash=" << FuncHash << ")\n";
  }

  OS << "  # of " << EntryName << " overlap: " << Overlap.NumEntries << "\n";
  if (Mismatch.NumEntries)
    OS << "  # of " << EntryName << " mismatch: " << Mismatch.NumEntries
       << "\n";
  if (Unique.NumEntries)
    OS << "  # of " << EntryName
       << " only in test_profile: " << Unique.NumEntries << "\n";

  OS << "  Edge profile overlap: " << format("%.3f%%", Overlap.CountSum * 100)
     << "\n";
  if (Mismatch.NumEntries)
    OS << "  Mismatched count percentage (Edge): "
       << format("%.3f%%", Mismatch.CountSum * 100) << "\n";
  if (Unique.NumEntries)
    OS << "  Percentage of Edge profile only in test_profile: "
       << format("%.3f%%", Unique.CountSum * 100) << "\n";
  OS << "  Edge profile base count sum: " << format("%.0f", Base.CountSum)
     << "\n"
     << "  Edge profile test count sum: " << format("%.0f", Test.CountSum)
     << "\n";

  for (unsigned I = 0; I < IPVK_Last - IPVK_First + 1; I++) {
    if (Base.ValueCounts[I] < 1.0f && Test.ValueCounts[I] < 1.0f)
      continue;
    char ProfileKindName[20] = {0};
    switch (I) {
    case IPVK_IndirectCallTarget:
      strncpy(ProfileKindName, "IndirectCall", 19);
      break;
    case IPVK_MemOPSize:
      strncpy(ProfileKindName, "MemOP", 19);
      break;
    case IPVK_VTableTarget:
      strncpy(ProfileKindName, "VTable", 19);
      break;
    default:
      snprintf(ProfileKindName, 19, "VP[%d]", I);
      break;
    }
    OS << "  " << ProfileKindName
       << " profile overlap: " << format("%.3f%%", Overlap.ValueCounts[I] * 100)
       << "\n";
    if (Mismatch.NumEntries)
      OS << "  Mismatched count percentage (" << ProfileKindName
         << "): " << format("%.3f%%", Mismatch.ValueCounts[I] * 100) << "\n";
    if (Unique.NumEntries)
      OS << "  Percentage of " << ProfileKindName
         << " profile only in test_profile: "
         << format("%.3f%%", Unique.ValueCounts[I] * 100) << "\n";
    OS << "  " << ProfileKindName
       << " profile base count sum: " << format("%.0f", Base.ValueCounts[I])
       << "\n"
       << "  " << ProfileKindName
       << " profile test count sum: " << format("%.0f", Test.ValueCounts[I])
       << "\n";
  }
}

namespace IndexedInstrProf {
Expected<Header> Header::readFromBuffer(const unsigned char *Buffer) {
  using namespace support;
  static_assert(std::is_standard_layout_v<Header>,
                "Use standard layout for Header for simplicity");
  Header H;

  H.Magic = endian::readNext<uint64_t, llvm::endianness::little>(Buffer);
  // Check the magic number.
  if (H.Magic != IndexedInstrProf::Magic)
    return make_error<InstrProfError>(instrprof_error::bad_magic);

  // Read the version.
  H.Version = endian::readNext<uint64_t, llvm::endianness::little>(Buffer);
  if (H.getIndexedProfileVersion() >
      IndexedInstrProf::ProfVersion::CurrentVersion)
    return make_error<InstrProfError>(instrprof_error::unsupported_version);

  static_assert(IndexedInstrProf::ProfVersion::CurrentVersion == Version12,
                "Please update the reader as needed when a new field is added "
                "or when indexed profile version gets bumped.");

  Buffer += sizeof(uint64_t); // Skip Header.Unused field.
  H.HashType = endian::readNext<uint64_t, llvm::endianness::little>(Buffer);
  H.HashOffset = endian::readNext<uint64_t, llvm::endianness::little>(Buffer);
  if (H.getIndexedProfileVersion() >= 8)
    H.MemProfOffset =
        endian::readNext<uint64_t, llvm::endianness::little>(Buffer);
  if (H.getIndexedProfileVersion() >= 9)
    H.BinaryIdOffset =
        endian::readNext<uint64_t, llvm::endianness::little>(Buffer);
  // Version 11 is handled by this condition.
  if (H.getIndexedProfileVersion() >= 10)
    H.TemporalProfTracesOffset =
        endian::readNext<uint64_t, llvm::endianness::little>(Buffer);
  if (H.getIndexedProfileVersion() >= 12)
    H.VTableNamesOffset =
        endian::readNext<uint64_t, llvm::endianness::little>(Buffer);
  return H;
}

uint64_t Header::getIndexedProfileVersion() const {
  return GET_VERSION(Version);
}

size_t Header::size() const {
  switch (getIndexedProfileVersion()) {
    // To retain backward compatibility, new fields must be appended to the end
    // of the header, and byte offset of existing fields shouldn't change when
    // indexed profile version gets incremented.
    static_assert(
        IndexedInstrProf::ProfVersion::CurrentVersion == Version12,
        "Please update the size computation below if a new field has "
        "been added to the header; for a version bump without new "
        "fields, add a case statement to fall through to the latest version.");
  case 12ull:
    return 72;
  case 11ull:
    [[fallthrough]];
  case 10ull:
    return 64;
  case 9ull:
    return 56;
  case 8ull:
    return 48;
  default: // Version7 (when the backwards compatible header was introduced).
    return 40;
  }
}

} // namespace IndexedInstrProf

} // end namespace llvm
