Esempio n. 1
0
static void traverseAllValueSites(const InstrProfRecord &Func, uint32_t VK,
                                  ValueSitesStats &Stats, raw_fd_ostream &OS,
                                  InstrProfSymtab *Symtab) {
  uint32_t NS = Func.getNumValueSites(VK);
  Stats.TotalNumValueSites += NS;
  for (size_t I = 0; I < NS; ++I) {
    uint32_t NV = Func.getNumValueDataForSite(VK, I);
    std::unique_ptr<InstrProfValueData[]> VD = Func.getValueForSite(VK, I);
    Stats.TotalNumValues += NV;
    if (NV) {
      Stats.TotalNumValueSitesWithValueProfile++;
      if (NV > Stats.ValueSitesHistogram.size())
        Stats.ValueSitesHistogram.resize(NV, 0);
      Stats.ValueSitesHistogram[NV - 1]++;
    }
    for (uint32_t V = 0; V < NV; V++) {
      OS << "\t[ " << I << ", ";
      if (Symtab == nullptr)
        OS << VD[V].Value;
      else
        OS << Symtab->getFuncName(VD[V].Value);
      OS << ", " << VD[V].Count << " ]\n";
    }
  }
}
Esempio n. 2
0
static std::error_code combineInstrProfRecords(InstrProfRecord &Dest,
                                               InstrProfRecord &Source,
                                               uint64_t &MaxFunctionCount) {
  // If the number of counters doesn't match we either have bad data
  // or a hash collision.
  if (Dest.Counts.size() != Source.Counts.size())
    return instrprof_error::count_mismatch;

  for (size_t I = 0, E = Source.Counts.size(); I < E; ++I) {
    if (Dest.Counts[I] + Source.Counts[I] < Dest.Counts[I])
      return instrprof_error::counter_overflow;
    Dest.Counts[I] += Source.Counts[I];
  }

  for (uint32_t Kind = IPVK_First; Kind <= IPVK_Last; ++Kind) {
    if (std::error_code EC = Dest.mergeValueProfData(Kind, Source))
      return EC;
  }

  // We keep track of the max function count as we go for simplicity.
  if (Dest.Counts[0] > MaxFunctionCount)
    MaxFunctionCount = Dest.Counts[0];

  return instrprof_error::success;
}
Esempio n. 3
0
std::error_code
RawInstrProfReader<IntPtrT>::readValueProfilingData(InstrProfRecord &Record) {

  Record.clearValueData();
  CurValueDataSize = 0;
  // Need to match the logic in value profile dumper code in compiler-rt:
  uint32_t NumValueKinds = 0;
  for (uint32_t I = 0; I < IPVK_Last + 1; I++)
    NumValueKinds += (Data->NumValueSites[I] != 0);

  if (!NumValueKinds)
    return success();

  ErrorOr<std::unique_ptr<ValueProfData>> VDataPtrOrErr =
      ValueProfData::getValueProfData(ValueDataStart,
                                      (const unsigned char *)ProfileEnd,
                                      getDataEndianness());

  if (VDataPtrOrErr.getError())
    return VDataPtrOrErr.getError();

  // Note that besides deserialization, this also performs the conversion for
  // indirect call targets.  The function pointers from the raw profile are
  // remapped into function name hashes.
  VDataPtrOrErr.get()->deserializeTo(Record, &Symtab->getAddrHashMap());
  CurValueDataSize = VDataPtrOrErr.get()->getSize();
  return success();
}
Esempio n. 4
0
std::error_code
RawInstrProfReader<IntPtrT>::readValueProfilingData(InstrProfRecord &Record) {

  Record.clearValueData();
  CurValueDataSize = 0;
  // Need to match the logic in value profile dumper code in compiler-rt:
  uint32_t NumValueKinds = 0;
  for (uint32_t I = 0; I < IPVK_Last + 1; I++)
    NumValueKinds += (Data->NumValueSites[I] != 0);

  if (!NumValueKinds)
    return success();

  ErrorOr<std::unique_ptr<ValueProfData>> VDataPtrOrErr =
      ValueProfData::getValueProfData(ValueDataStart,
                                      (const unsigned char *)ProfileEnd,
                                      getDataEndianness());

  if (VDataPtrOrErr.getError())
    return VDataPtrOrErr.getError();

  VDataPtrOrErr.get()->deserializeTo(Record, &Symtab->getAddrHashMap());
  CurValueDataSize = VDataPtrOrErr.get()->getSize();
  return success();
}
Esempio n. 5
0
std::error_code RawInstrProfReader<IntPtrT>::readValueProfilingData(
    InstrProfRecord &Record) {

  Record.clearValueData();
  if (!Data->Values || (ValueDataDelta == 0))
    return success();

  // Read value data.
  uint64_t NumVSites = 0;
  for (uint32_t Kind = IPVK_First; Kind <= ValueKindLast; ++Kind)
    NumVSites += swap(Data->NumValueSites[Kind]);
  NumVSites += getNumPaddingBytes(NumVSites);

  auto VDataCounts = makeArrayRef(getValueDataCounts(Data->Values), NumVSites);
  // Check bounds.
  if (VDataCounts.data() < ValueDataStart ||
      VDataCounts.data() + VDataCounts.size() >
          reinterpret_cast<const uint8_t *>(ProfileEnd))
    return error(instrprof_error::malformed);

  const InstrProfValueData *VDataPtr =
      getValueData(swap(Data->Values) + NumVSites);
  for (uint32_t Kind = IPVK_First; Kind <= ValueKindLast; ++Kind) {
    NumVSites = swap(Data->NumValueSites[Kind]);
    Record.reserveSites(Kind, NumVSites);
    for (uint32_t VSite = 0; VSite < NumVSites; ++VSite) {

      uint32_t VDataCount = VDataCounts[VSite];
      if ((const char *)(VDataPtr + VDataCount) > ProfileEnd)
        return error(instrprof_error::malformed);

      std::vector<InstrProfValueData> CurrentValues;
      CurrentValues.reserve(VDataCount);
      for (uint32_t VIndex = 0; VIndex < VDataCount; ++VIndex) {
        uint64_t TargetValue = swap(VDataPtr->Value);
        uint64_t Count = swap(VDataPtr->Count);
        CurrentValues.push_back({TargetValue, Count});
        ++VDataPtr;
      }
      Record.addValueData(Kind, VSite, CurrentValues.data(),
                          VDataCount, &FunctionPtrToNameMap);
    }
  }
  return success();
}
Esempio n. 6
0
void InstrProfWriter::writeRecordInText(StringRef Name, uint64_t Hash,
                                        const InstrProfRecord &Func,
                                        InstrProfSymtab &Symtab,
                                        raw_fd_ostream &OS) {
  OS << Name << "\n";
  OS << "# Func Hash:\n" << Hash << "\n";
  OS << "# Num Counters:\n" << Func.Counts.size() << "\n";
  OS << "# Counter Values:\n";
  for (uint64_t Count : Func.Counts)
    OS << Count << "\n";

  uint32_t NumValueKinds = Func.getNumValueKinds();
  if (!NumValueKinds) {
    OS << "\n";
    return;
  }

  OS << "# Num Value Kinds:\n" << Func.getNumValueKinds() << "\n";
  for (uint32_t VK = 0; VK < IPVK_Last + 1; VK++) {
    uint32_t NS = Func.getNumValueSites(VK);
    if (!NS)
      continue;
    OS << "# ValueKind = " << ValueProfKindStr[VK] << ":\n" << VK << "\n";
    OS << "# NumValueSites:\n" << NS << "\n";
    for (uint32_t S = 0; S < NS; S++) {
      uint32_t ND = Func.getNumValueDataForSite(VK, S);
      OS << ND << "\n";
      std::unique_ptr<InstrProfValueData[]> VD = Func.getValueForSite(VK, S);
      for (uint32_t I = 0; I < ND; I++) {
        if (VK == IPVK_IndirectCallTarget)
          OS << Symtab.getFuncNameOrExternalSymbol(VD[I].Value) << ":"
             << VD[I].Count << "\n";
        else
          OS << VD[I].Value << ":" << VD[I].Count << "\n";
      }
    }
  }

  OS << "\n";
}
Esempio n. 7
0
void InstrProfWriter::updateStringTableReferences(InstrProfRecord &I) {
  I.updateStrings(&StringTable);
}
Esempio n. 8
0
std::error_code
TextInstrProfReader::readValueProfileData(InstrProfRecord &Record) {

#define CHECK_LINE_END(Line)                                                   \
  if (Line.is_at_end())                                                        \
    return error(instrprof_error::truncated);
#define READ_NUM(Str, Dst)                                                     \
  if ((Str).getAsInteger(10, (Dst)))                                           \
    return error(instrprof_error::malformed);
#define VP_READ_ADVANCE(Val)                                                   \
  CHECK_LINE_END(Line);                                                        \
  uint32_t Val;                                                                \
  READ_NUM((*Line), (Val));                                                    \
  Line++;

  if (Line.is_at_end())
    return success();

  uint32_t NumValueKinds;
  if (Line->getAsInteger(10, NumValueKinds)) {
    // No value profile data
    return success();
  }
  if (NumValueKinds == 0 || NumValueKinds > IPVK_Last + 1)
    return error(instrprof_error::malformed);
  Line++;

  for (uint32_t VK = 0; VK < NumValueKinds; VK++) {
    VP_READ_ADVANCE(ValueKind);
    if (ValueKind > IPVK_Last)
      return error(instrprof_error::malformed);
    VP_READ_ADVANCE(NumValueSites);
    if (!NumValueSites)
      continue;

    Record.reserveSites(VK, NumValueSites);
    for (uint32_t S = 0; S < NumValueSites; S++) {
      VP_READ_ADVANCE(NumValueData);

      std::vector<InstrProfValueData> CurrentValues;
      for (uint32_t V = 0; V < NumValueData; V++) {
        CHECK_LINE_END(Line);
        std::pair<StringRef, StringRef> VD = Line->split(':');
        uint64_t TakenCount, Value;
        if (VK == IPVK_IndirectCallTarget) {
          Symtab->addFuncName(VD.first);
          Value = IndexedInstrProf::ComputeHash(VD.first);
        } else {
          READ_NUM(VD.first, Value);
        }
        READ_NUM(VD.second, TakenCount);
        CurrentValues.push_back({Value, TakenCount});
        Line++;
      }
      Record.addValueData(VK, S, CurrentValues.data(), NumValueData, nullptr);
    }
  }
  return success();

#undef CHECK_LINE_END
#undef READ_NUM
#undef VP_READ_ADVANCE
}