//=-- Profilesummary.cpp - Profile summary 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 converting profile summary data from/to
// metadata.
//
//===----------------------------------------------------------------------===//

#include "llvm/IR/ProfileSummary.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Format.h"

using namespace llvm;

// Return an MDTuple with two elements. The first element is a string Key and
// the second is a uint64_t Value.
static Metadata *getKeyValMD(LLVMContext &Context, const char *Key,
                             uint64_t Val) {
  Type *Int64Ty = Type::getInt64Ty(Context);
  Metadata *Ops[2] = {MDString::get(Context, Key),
                      ConstantAsMetadata::get(ConstantInt::get(Int64Ty, Val))};
  return MDTuple::get(Context, Ops);
}

static Metadata *getKeyFPValMD(LLVMContext &Context, const char *Key,
                               double Val) {
  Type *DoubleTy = Type::getDoubleTy(Context);
  Metadata *Ops[2] = {MDString::get(Context, Key),
                      ConstantAsMetadata::get(ConstantFP::get(DoubleTy, Val))};
  return MDTuple::get(Context, Ops);
}

// Return an MDTuple with two elements. The first element is a string Key and
// the second is a string Value.
static Metadata *getKeyValMD(LLVMContext &Context, const char *Key,
                             const char *Val) {
  Metadata *Ops[2] = {MDString::get(Context, Key), MDString::get(Context, Val)};
  return MDTuple::get(Context, Ops);
}

// This returns an MDTuple representing the detiled summary. The tuple has two
// elements: a string "DetailedSummary" and an MDTuple representing the value
// of the detailed summary. Each element of this tuple is again an MDTuple whose
// elements are the (Cutoff, MinCount, NumCounts) triplet of the
// DetailedSummaryEntry.
Metadata *ProfileSummary::getDetailedSummaryMD(LLVMContext &Context) {
  std::vector<Metadata *> Entries;
  Type *Int32Ty = Type::getInt32Ty(Context);
  Type *Int64Ty = Type::getInt64Ty(Context);
  for (auto &Entry : DetailedSummary) {
    Metadata *EntryMD[3] = {
        ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Entry.Cutoff)),
        ConstantAsMetadata::get(ConstantInt::get(Int64Ty, Entry.MinCount)),
        ConstantAsMetadata::get(ConstantInt::get(Int32Ty, Entry.NumCounts))};
    Entries.push_back(MDTuple::get(Context, EntryMD));
  }
  Metadata *Ops[2] = {MDString::get(Context, "DetailedSummary"),
                      MDTuple::get(Context, Entries)};
  return MDTuple::get(Context, Ops);
}

// This returns an MDTuple representing this ProfileSummary object. The first
// entry of this tuple is another MDTuple of two elements: a string
// "ProfileFormat" and a string representing the format ("InstrProf" or
// "SampleProfile"). The rest of the elements of the outer MDTuple are specific
// to the kind of profile summary as returned by getFormatSpecificMD.
// IsPartialProfile is an optional field and \p AddPartialField will decide
// whether to add a field for it.
// PartialProfileRatio is an optional field and \p AddPartialProfileRatioField
// will decide whether to add a field for it.
Metadata *ProfileSummary::getMD(LLVMContext &Context, bool AddPartialField,
                                bool AddPartialProfileRatioField) {
  const char *KindStr[3] = {"InstrProf", "CSInstrProf", "SampleProfile"};
  SmallVector<Metadata *, 16> Components;
  Components.push_back(getKeyValMD(Context, "ProfileFormat", KindStr[PSK]));
  Components.push_back(getKeyValMD(Context, "TotalCount", getTotalCount()));
  Components.push_back(getKeyValMD(Context, "MaxCount", getMaxCount()));
  Components.push_back(
      getKeyValMD(Context, "MaxInternalCount", getMaxInternalCount()));
  Components.push_back(
      getKeyValMD(Context, "MaxFunctionCount", getMaxFunctionCount()));
  Components.push_back(getKeyValMD(Context, "NumCounts", getNumCounts()));
  Components.push_back(getKeyValMD(Context, "NumFunctions", getNumFunctions()));
  if (AddPartialField)
    Components.push_back(
        getKeyValMD(Context, "IsPartialProfile", isPartialProfile()));
  if (AddPartialProfileRatioField)
    Components.push_back(getKeyFPValMD(Context, "PartialProfileRatio",
                                       getPartialProfileRatio()));
  Components.push_back(getDetailedSummaryMD(Context));
  return MDTuple::get(Context, Components);
}

// Get the value metadata for the input MD/Key.
static ConstantAsMetadata *getValMD(MDTuple *MD, const char *Key) {
  if (!MD)
    return nullptr;
  if (MD->getNumOperands() != 2)
    return nullptr;
  MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0));
  ConstantAsMetadata *ValMD = dyn_cast<ConstantAsMetadata>(MD->getOperand(1));
  if (!KeyMD || !ValMD)
    return nullptr;
  if (!KeyMD->getString().equals(Key))
    return nullptr;
  return ValMD;
}

// Parse an MDTuple representing (Key, Val) pair.
static bool getVal(MDTuple *MD, const char *Key, uint64_t &Val) {
  if (auto *ValMD = getValMD(MD, Key)) {
    Val = cast<ConstantInt>(ValMD->getValue())->getZExtValue();
    return true;
  }
  return false;
}

static bool getVal(MDTuple *MD, const char *Key, double &Val) {
  if (auto *ValMD = getValMD(MD, Key)) {
    Val = cast<ConstantFP>(ValMD->getValue())->getValueAPF().convertToDouble();
    return true;
  }
  return false;
}

// Check if an MDTuple represents a (Key, Val) pair.
static bool isKeyValuePair(MDTuple *MD, const char *Key, const char *Val) {
  if (!MD || MD->getNumOperands() != 2)
    return false;
  MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0));
  MDString *ValMD = dyn_cast<MDString>(MD->getOperand(1));
  if (!KeyMD || !ValMD)
    return false;
  if (!KeyMD->getString().equals(Key) || !ValMD->getString().equals(Val))
    return false;
  return true;
}

// Parse an MDTuple representing detailed summary.
static bool getSummaryFromMD(MDTuple *MD, SummaryEntryVector &Summary) {
  if (!MD || MD->getNumOperands() != 2)
    return false;
  MDString *KeyMD = dyn_cast<MDString>(MD->getOperand(0));
  if (!KeyMD || !KeyMD->getString().equals("DetailedSummary"))
    return false;
  MDTuple *EntriesMD = dyn_cast<MDTuple>(MD->getOperand(1));
  if (!EntriesMD)
    return false;
  for (auto &&MDOp : EntriesMD->operands()) {
    MDTuple *EntryMD = dyn_cast<MDTuple>(MDOp);
    if (!EntryMD || EntryMD->getNumOperands() != 3)
      return false;
    ConstantAsMetadata *Op0 =
        dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(0));
    ConstantAsMetadata *Op1 =
        dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(1));
    ConstantAsMetadata *Op2 =
        dyn_cast<ConstantAsMetadata>(EntryMD->getOperand(2));

    if (!Op0 || !Op1 || !Op2)
      return false;
    Summary.emplace_back(cast<ConstantInt>(Op0->getValue())->getZExtValue(),
                         cast<ConstantInt>(Op1->getValue())->getZExtValue(),
                         cast<ConstantInt>(Op2->getValue())->getZExtValue());
  }
  return true;
}

// Get the value of an optional field. Increment 'Idx' if it was present. Return
// true if we can move onto the next field.
template <typename ValueType>
static bool getOptionalVal(MDTuple *Tuple, unsigned &Idx, const char *Key,
                           ValueType &Value) {
  if (getVal(dyn_cast<MDTuple>(Tuple->getOperand(Idx)), Key, Value)) {
    Idx++;
    // Need to make sure when the key is present, we won't step over the bound
    // of Tuple operand array. Since (non-optional) DetailedSummary always comes
    // last, the next entry in the tuple operand array must exist.
    return Idx < Tuple->getNumOperands();
  }
  // It was absent, keep going.
  return true;
}

ProfileSummary *ProfileSummary::getFromMD(Metadata *MD) {
  MDTuple *Tuple = dyn_cast_or_null<MDTuple>(MD);
  if (!Tuple || Tuple->getNumOperands() < 8 || Tuple->getNumOperands() > 10)
    return nullptr;

  unsigned I = 0;
  auto &FormatMD = Tuple->getOperand(I++);
  ProfileSummary::Kind SummaryKind;
  if (isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat",
                     "SampleProfile"))
    SummaryKind = PSK_Sample;
  else if (isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat",
                          "InstrProf"))
    SummaryKind = PSK_Instr;
  else if (isKeyValuePair(dyn_cast_or_null<MDTuple>(FormatMD), "ProfileFormat",
                          "CSInstrProf"))
    SummaryKind = PSK_CSInstr;
  else
    return nullptr;

  uint64_t NumCounts, TotalCount, NumFunctions, MaxFunctionCount, MaxCount,
      MaxInternalCount;
  if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(I++)), "TotalCount",
              TotalCount))
    return nullptr;
  if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(I++)), "MaxCount", MaxCount))
    return nullptr;
  if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(I++)), "MaxInternalCount",
              MaxInternalCount))
    return nullptr;
  if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(I++)), "MaxFunctionCount",
              MaxFunctionCount))
    return nullptr;
  if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(I++)), "NumCounts",
              NumCounts))
    return nullptr;
  if (!getVal(dyn_cast<MDTuple>(Tuple->getOperand(I++)), "NumFunctions",
              NumFunctions))
    return nullptr;

  // Optional fields. Need to initialize because the fields are optional.
  uint64_t IsPartialProfile = 0;
  if (!getOptionalVal(Tuple, I, "IsPartialProfile", IsPartialProfile))
    return nullptr;
  double PartialProfileRatio = 0;
  if (!getOptionalVal(Tuple, I, "PartialProfileRatio", PartialProfileRatio))
    return nullptr;

  SummaryEntryVector Summary;
  if (!getSummaryFromMD(dyn_cast<MDTuple>(Tuple->getOperand(I++)), Summary))
    return nullptr;
  return new ProfileSummary(SummaryKind, std::move(Summary), TotalCount,
                            MaxCount, MaxInternalCount, MaxFunctionCount,
                            NumCounts, NumFunctions, IsPartialProfile,
                            PartialProfileRatio);
}

void ProfileSummary::printSummary(raw_ostream &OS) {
  OS << "Total functions: " << NumFunctions << "\n";
  OS << "Maximum function count: " << MaxFunctionCount << "\n";
  OS << "Maximum block count: " << MaxCount << "\n";
  OS << "Total number of blocks: " << NumCounts << "\n";
  OS << "Total count: " << TotalCount << "\n";
}

void ProfileSummary::printDetailedSummary(raw_ostream &OS) {
  OS << "Detailed summary:\n";
  for (const auto &Entry : DetailedSummary) {
    OS << Entry.NumCounts << " blocks with count >= " << Entry.MinCount
       << " account for "
       << format("%0.6g", (float)Entry.Cutoff / Scale * 100)
       << " percentage of the total counts.\n";
  }
}
