+ // Populate the hash table generator.
+ for (const auto &I : FunctionData)
+ Generator.insert(I.getKey(), &I.getValue());
+
+ using namespace llvm::support;
+ endian::Writer<little> LE(OS);
+
+ // Write the header.
+ IndexedInstrProf::Header Header;
+ Header.Magic = IndexedInstrProf::Magic;
+ Header.Version = IndexedInstrProf::Version;
+ Header.MaxFunctionCount = MaxFunctionCount;
+ Header.HashType = static_cast<uint64_t>(IndexedInstrProf::HashType);
+ Header.HashOffset = 0;
+ int N = sizeof(IndexedInstrProf::Header) / sizeof(uint64_t);
+
+ // Only write out all the fields execpt 'HashOffset'. We need
+ // to remember the offset of that field to allow back patching
+ // later.
+ for (int I = 0; I < N - 1; I++)
+ LE.write<uint64_t>(reinterpret_cast<uint64_t *>(&Header)[I]);
+
+ // Save a space to write the hash table start location.
+ uint64_t HashTableStartLoc = OS.tell();
+ // Reserve the space for HashOffset field.
+ LE.write<uint64_t>(0);
+ // Write the hash table.
+ uint64_t HashTableStart = Generator.Emit(OS);
+
+ return std::make_pair(HashTableStartLoc, HashTableStart);
+}
+
+void InstrProfWriter::write(raw_fd_ostream &OS) {
+ // Write the hash table.
+ auto TableStart = writeImpl(OS);
+
+ // Go back and fill in the hash table start.
+ using namespace support;
+ OS.seek(TableStart.first);
+ // Now patch the HashOffset field previously reserved.
+ endian::Writer<little>(OS).write<uint64_t>(TableStart.second);
+}
+
+static const char *ValueProfKindStr[] = {
+#define VALUE_PROF_KIND(Enumerator, Value) #Enumerator,
+#include "llvm/ProfileData/InstrProfData.inc"
+};
+
+void InstrProfWriter::writeRecordInText(const InstrProfRecord &Func,
+ InstrProfSymtab &Symtab,
+ raw_fd_ostream &OS) {
+ OS << Func.Name << "\n";
+ OS << "# Func Hash:\n" << Func.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) {