From e50a38840dc3db5813f74b1cd2e10e6d984d0e67 Mon Sep 17 00:00:00 2001 From: Gulfem Savrun Yeniceri Date: Thu, 6 May 2021 16:09:12 +0000 Subject: [PATCH] [profile] Add binary id into profiles This patch adds binary id into profiles to easily associate binaries with the corresponding profiles. There is an RFC that discusses the motivation, design and implementation in more detail: https://lists.llvm.org/pipermail/llvm-dev/2021-June/151154.html Differential Revision: https://reviews.llvm.org/D102039 --- compiler-rt/include/profile/InstrProfData.inc | 3 +- .../lib/profile/InstrProfilingInternal.h | 6 + .../profile/InstrProfilingPlatformDarwin.c | 6 + .../lib/profile/InstrProfilingPlatformLinux.c | 108 ++++++++++++++++++ .../lib/profile/InstrProfilingPlatformOther.c | 5 + .../profile/InstrProfilingPlatformWindows.c | 5 + .../lib/profile/InstrProfilingWriter.c | 16 ++- compiler-rt/test/profile/Linux/binary-id.c | 36 ++++++ .../test/profile/Linux/corrupted-profile.c | 4 +- llvm/include/llvm/ProfileData/InstrProf.h | 1 + .../llvm/ProfileData/InstrProfData.inc | 3 +- .../llvm/ProfileData/InstrProfReader.h | 7 ++ llvm/lib/ProfileData/InstrProfReader.cpp | 37 +++++- .../llvm-profdata/Inputs/c-general.profraw | Bin 1696 -> 1800 bytes .../llvm-profdata/Inputs/compressed.profraw | Bin 1648 -> 1752 bytes llvm/test/tools/llvm-profdata/c-general.test | 2 +- .../malformed-ptr-to-counter-array.test | 4 +- .../tools/llvm-profdata/raw-32-bits-be.test | 3 +- .../tools/llvm-profdata/raw-32-bits-le.test | 3 +- .../tools/llvm-profdata/raw-64-bits-be.test | 3 +- .../tools/llvm-profdata/raw-64-bits-le.test | 3 +- .../tools/llvm-profdata/raw-two-profiles.test | 6 +- llvm/tools/llvm-profdata/llvm-profdata.cpp | 19 ++- 23 files changed, 256 insertions(+), 24 deletions(-) create mode 100644 compiler-rt/test/profile/Linux/binary-id.c diff --git a/compiler-rt/include/profile/InstrProfData.inc b/compiler-rt/include/profile/InstrProfData.inc index bd625457260f59..08a64246962782 100644 --- a/compiler-rt/include/profile/InstrProfData.inc +++ b/compiler-rt/include/profile/InstrProfData.inc @@ -137,6 +137,7 @@ INSTR_PROF_RAW_HEADER(uint64_t, NamesSize, NamesSize) INSTR_PROF_RAW_HEADER(uint64_t, CountersDelta, (uintptr_t)CountersBegin) INSTR_PROF_RAW_HEADER(uint64_t, NamesDelta, (uintptr_t)NamesBegin) INSTR_PROF_RAW_HEADER(uint64_t, ValueKindLast, IPVK_Last) +INSTR_PROF_RAW_HEADER(uint64_t, BinaryIdsSize, __llvm_write_binary_ids(NULL)) #undef INSTR_PROF_RAW_HEADER /* INSTR_PROF_RAW_HEADER end */ @@ -645,7 +646,7 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure, (uint64_t)'f' << 16 | (uint64_t)'R' << 8 | (uint64_t)129 /* Raw profile format version (start from 1). */ -#define INSTR_PROF_RAW_VERSION 5 +#define INSTR_PROF_RAW_VERSION 6 /* Indexed profile format version (start from 1). */ #define INSTR_PROF_INDEX_VERSION 7 /* Coverage mapping format version (start from 0). */ diff --git a/compiler-rt/lib/profile/InstrProfilingInternal.h b/compiler-rt/lib/profile/InstrProfilingInternal.h index b2fd735769d988..ffa790a4cb66ef 100644 --- a/compiler-rt/lib/profile/InstrProfilingInternal.h +++ b/compiler-rt/lib/profile/InstrProfilingInternal.h @@ -193,4 +193,10 @@ COMPILER_RT_VISIBILITY extern ValueProfNode *CurrentVNode; COMPILER_RT_VISIBILITY extern ValueProfNode *EndVNode; extern void (*VPMergeHook)(struct ValueProfData *, __llvm_profile_data *); +/* + * Write binary ids into profiles if writer is given. + * Return -1 if an error occurs, otherwise, return total size of binary ids. + */ +int __llvm_write_binary_ids(ProfDataWriter *Writer); + #endif diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformDarwin.c b/compiler-rt/lib/profile/InstrProfilingPlatformDarwin.c index 29541c74d5a638..c2e7fad98386f1 100644 --- a/compiler-rt/lib/profile/InstrProfilingPlatformDarwin.c +++ b/compiler-rt/lib/profile/InstrProfilingPlatformDarwin.c @@ -10,6 +10,7 @@ // with freestanding compilation. See `darwin_add_builtin_libraries`. #include "InstrProfiling.h" +#include "InstrProfilingInternal.h" #if defined(__APPLE__) /* Use linker magic to find the bounds of the Data section. */ @@ -67,4 +68,9 @@ ValueProfNode *__llvm_profile_end_vnodes(void) { return &VNodesEnd; } COMPILER_RT_VISIBILITY ValueProfNode *CurrentVNode = &VNodesStart; COMPILER_RT_VISIBILITY ValueProfNode *EndVNode = &VNodesEnd; + +COMPILER_RT_VISIBILITY int __llvm_write_binary_ids(ProfDataWriter *Writer) { + return 0; +} + #endif diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c b/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c index 07f3578dc43b1a..508624a80cd66e 100644 --- a/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c +++ b/compiler-rt/lib/profile/InstrProfilingPlatformLinux.c @@ -9,9 +9,13 @@ #if defined(__linux__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \ (defined(__sun__) && defined(__svr4__)) || defined(__NetBSD__) +#include +#include #include +#include #include "InstrProfiling.h" +#include "InstrProfilingInternal.h" #define PROF_DATA_START INSTR_PROF_SECT_START(INSTR_PROF_DATA_COMMON) #define PROF_DATA_STOP INSTR_PROF_SECT_STOP(INSTR_PROF_DATA_COMMON) @@ -72,4 +76,108 @@ COMPILER_RT_VISIBILITY ValueProfNode *__llvm_profile_end_vnodes(void) { COMPILER_RT_VISIBILITY ValueProfNode *CurrentVNode = &PROF_VNODES_START; COMPILER_RT_VISIBILITY ValueProfNode *EndVNode = &PROF_VNODES_STOP; +static size_t RoundUp(size_t size, size_t align) { + return (size + align - 1) & ~(align - 1); +} + +/* + * Write binary id length and then its data, because binary id does not + * have a fixed length. + */ +int WriteOneBinaryId(ProfDataWriter *Writer, uint64_t BinaryIdLen, + const uint8_t *BinaryIdData) { + ProfDataIOVec BinaryIdIOVec[] = { + {&BinaryIdLen, sizeof(uint64_t), 1, 0}, + {BinaryIdData, sizeof(uint8_t), BinaryIdLen, 0}}; + if (Writer->Write(Writer, BinaryIdIOVec, + sizeof(BinaryIdIOVec) / sizeof(*BinaryIdIOVec))) + return -1; + + /* Successfully wrote binary id, report success. */ + return 0; +} + +/* + * Look for the note that has the name "GNU\0" and type NT_GNU_BUILD_ID + * that contains build id. If build id exists, write binary id. + * + * Each note in notes section starts with a struct which includes + * n_namesz, n_descsz, and n_type members. It is followed by the name + * (whose length is defined in n_namesz) and then by the descriptor + * (whose length is defined in n_descsz). + * + * Note sections like .note.ABI-tag and .note.gnu.build-id are aligned + * to 4 bytes, so round n_namesz and n_descsz to the nearest 4 bytes. + */ +int WriteBinaryIdForNote(ProfDataWriter *Writer, const ElfW(Nhdr) * Note) { + int BinaryIdSize = 0; + + const char *NoteName = (const char *)Note + sizeof(ElfW(Nhdr)); + if (Note->n_type == NT_GNU_BUILD_ID && Note->n_namesz == 4 && + memcmp(NoteName, "GNU\0", 4) == 0) { + + uint64_t BinaryIdLen = Note->n_descsz; + const uint8_t *BinaryIdData = + (const uint8_t *)(NoteName + RoundUp(Note->n_namesz, 4)); + if (Writer != NULL && + WriteOneBinaryId(Writer, BinaryIdLen, BinaryIdData) == -1) + return -1; + + BinaryIdSize = sizeof(BinaryIdLen) + BinaryIdLen; + } + + return BinaryIdSize; +} + +/* + * Helper function that iterates through notes section and find build ids. + * If writer is given, write binary ids into profiles. + * If an error happens while writing, return -1. + */ +int WriteBinaryIds(ProfDataWriter *Writer, const ElfW(Nhdr) * Note, + const ElfW(Nhdr) * NotesEnd) { + int TotalBinaryIdsSize = 0; + while (Note < NotesEnd) { + int Result = WriteBinaryIdForNote(Writer, Note); + if (Result == -1) + return -1; + TotalBinaryIdsSize += Result; + + /* Calculate the offset of the next note in notes section. */ + size_t NoteOffset = sizeof(ElfW(Nhdr)) + RoundUp(Note->n_namesz, 4) + + RoundUp(Note->n_descsz, 4); + Note = (const ElfW(Nhdr) *)((const char *)(Note) + NoteOffset); + } + + return TotalBinaryIdsSize; +} + +/* + * Write binary ids into profiles if writer is given. + * Return the total size of binary ids. + * If an error happens while writing, return -1. + */ +COMPILER_RT_VISIBILITY int __llvm_write_binary_ids(ProfDataWriter *Writer) { + extern const ElfW(Ehdr) __ehdr_start __attribute__((visibility("hidden"))); + const ElfW(Ehdr) *ElfHeader = &__ehdr_start; + const ElfW(Phdr) *ProgramHeader = + (const ElfW(Phdr) *)((uintptr_t)ElfHeader + ElfHeader->e_phoff); + + uint32_t I; + /* Iterate through entries in the program header. */ + for (I = 0; I < ElfHeader->e_phnum; I++) { + /* Look for the notes section in program header entries. */ + if (ProgramHeader[I].p_type != PT_NOTE) + continue; + + const ElfW(Nhdr) *Note = + (const ElfW(Nhdr) *)((uintptr_t)ElfHeader + ProgramHeader[I].p_offset); + const ElfW(Nhdr) *NotesEnd = + (const ElfW(Nhdr) *)((const char *)(Note) + ProgramHeader[I].p_filesz); + return WriteBinaryIds(Writer, Note, NotesEnd); + } + + return 0; +} + #endif diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformOther.c b/compiler-rt/lib/profile/InstrProfilingPlatformOther.c index 56c5d8378c29de..0e59148e2044d7 100644 --- a/compiler-rt/lib/profile/InstrProfilingPlatformOther.c +++ b/compiler-rt/lib/profile/InstrProfilingPlatformOther.c @@ -14,6 +14,7 @@ #include #include "InstrProfiling.h" +#include "InstrProfilingInternal.h" static const __llvm_profile_data *DataFirst = NULL; static const __llvm_profile_data *DataLast = NULL; @@ -97,4 +98,8 @@ ValueProfNode *__llvm_profile_end_vnodes(void) { return 0; } COMPILER_RT_VISIBILITY ValueProfNode *CurrentVNode = 0; COMPILER_RT_VISIBILITY ValueProfNode *EndVNode = 0; +COMPILER_RT_VISIBILITY int __llvm_write_binary_ids(ProfDataWriter *Writer) { + return 0; +} + #endif diff --git a/compiler-rt/lib/profile/InstrProfilingPlatformWindows.c b/compiler-rt/lib/profile/InstrProfilingPlatformWindows.c index 81b708bb2a38ff..a0192ced4f26b6 100644 --- a/compiler-rt/lib/profile/InstrProfilingPlatformWindows.c +++ b/compiler-rt/lib/profile/InstrProfilingPlatformWindows.c @@ -7,6 +7,7 @@ \*===----------------------------------------------------------------------===*/ #include "InstrProfiling.h" +#include "InstrProfilingInternal.h" #if defined(_WIN32) @@ -65,4 +66,8 @@ ValueProfNode *__llvm_profile_end_vnodes(void) { return &VNodesEnd; } ValueProfNode *CurrentVNode = &VNodesStart + 1; ValueProfNode *EndVNode = &VNodesEnd; +COMPILER_RT_VISIBILITY int __llvm_write_binary_ids(ProfDataWriter *Writer) { + return 0; +} + #endif diff --git a/compiler-rt/lib/profile/InstrProfilingWriter.c b/compiler-rt/lib/profile/InstrProfilingWriter.c index 16ad965ff6083f..25f630293227e1 100644 --- a/compiler-rt/lib/profile/InstrProfilingWriter.c +++ b/compiler-rt/lib/profile/InstrProfilingWriter.c @@ -283,16 +283,24 @@ lprofWriteDataImpl(ProfDataWriter *Writer, const __llvm_profile_data *DataBegin, #define INSTR_PROF_RAW_HEADER(Type, Name, Init) Header.Name = Init; #include "profile/InstrProfData.inc" - /* Write the data. */ - ProfDataIOVec IOVec[] = { - {&Header, sizeof(__llvm_profile_header), 1, 0}, + /* Write the profile header. */ + ProfDataIOVec IOVec[] = {{&Header, sizeof(__llvm_profile_header), 1, 0}}; + if (Writer->Write(Writer, IOVec, sizeof(IOVec) / sizeof(*IOVec))) + return -1; + + /* Write the binary id lengths and data. */ + if (__llvm_write_binary_ids(Writer) == -1) + return -1; + + /* Write the profile data. */ + ProfDataIOVec IOVecData[] = { {DataBegin, sizeof(__llvm_profile_data), DataSize, 0}, {NULL, sizeof(uint8_t), PaddingBytesBeforeCounters, 1}, {CountersBegin, sizeof(uint64_t), CountersSize, 0}, {NULL, sizeof(uint8_t), PaddingBytesAfterCounters, 1}, {SkipNameDataWrite ? NULL : NamesBegin, sizeof(uint8_t), NamesSize, 0}, {NULL, sizeof(uint8_t), PaddingBytesAfterNames, 1}}; - if (Writer->Write(Writer, IOVec, sizeof(IOVec) / sizeof(*IOVec))) + if (Writer->Write(Writer, IOVecData, sizeof(IOVecData) / sizeof(*IOVecData))) return -1; /* Value profiling is not yet supported in continuous mode. */ diff --git a/compiler-rt/test/profile/Linux/binary-id.c b/compiler-rt/test/profile/Linux/binary-id.c new file mode 100644 index 00000000000000..e165283718cb67 --- /dev/null +++ b/compiler-rt/test/profile/Linux/binary-id.c @@ -0,0 +1,36 @@ +// REQUIRES: linux +// RUN: %clang_profgen -Wl,--build-id=none -O2 -o %t %s +// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t +// RUN: llvm-profdata show --binary-ids %t.profraw > %t.out +// RUN: FileCheck %s --check-prefix=NO-BINARY-ID < %t.out +// RUN: llvm-profdata merge -o %t.profdata %t.profraw + +// RUN: %clang_profgen -Wl,--build-id -O2 -o %t %s +// RUN: env LLVM_PROFILE_FILE=%t.profraw %run %t +// RUN: llvm-profdata show --binary-ids %t.profraw > %t.profraw.out +// RUN: FileCheck %s --check-prefix=BINARY-ID-RAW-PROF < %t.profraw.out + +void foo() { +} + +void bar() { +} + +int main() { + foo(); + bar(); + return 0; +} + +// NO-BINARY-ID: Instrumentation level: Front-end +// NO-BINARY-ID-NEXT: Total functions: 3 +// NO-BINARY-ID-NEXT: Maximum function count: 1 +// NO-BINARY-ID-NEXT: Maximum internal block count: 0 +// NO-BINARY-ID-NOT: Binary IDs: + +// BINARY-ID-RAW-PROF: Instrumentation level: Front-end +// BINARY-ID-RAW-PROF-NEXT: Total functions: 3 +// BINARY-ID-RAW-PROF-NEXT: Maximum function count: 1 +// BINARY-ID-RAW-PROF-NEXT: Maximum internal block count: 0 +// BINARY-ID-RAW-PROF-NEXT: Binary IDs: +// BINARY-ID-RAW-PROF-NEXT: {{[0-9a-f]+}} diff --git a/compiler-rt/test/profile/Linux/corrupted-profile.c b/compiler-rt/test/profile/Linux/corrupted-profile.c index 4b8682bf8a7fe8..cbc37aca2ee284 100644 --- a/compiler-rt/test/profile/Linux/corrupted-profile.c +++ b/compiler-rt/test/profile/Linux/corrupted-profile.c @@ -43,9 +43,9 @@ int main(int argc, char** argv) { bail("mmap"); // We're trying to make the first CounterPtr invalid. - // 10 64-bit words as header. + // 11 64-bit words as header. // CounterPtr is the third 64-bit word field. - memset(&Buf[10 * 8 + 2 * 8], 0xAB, 8); + memset(&Buf[11 * 8 + 2 * 8], 0xAB, 8); if (munmap(Buf, FileSize)) bail("munmap"); diff --git a/llvm/include/llvm/ProfileData/InstrProf.h b/llvm/include/llvm/ProfileData/InstrProf.h index 1681c048070635..08a934e6985fed 100644 --- a/llvm/include/llvm/ProfileData/InstrProf.h +++ b/llvm/include/llvm/ProfileData/InstrProf.h @@ -1103,6 +1103,7 @@ namespace RawInstrProf { // raw header. // Version 5: Bit 60 of FuncHash is reserved for the flag for the context // sensitive records. +// Version 6: Added binary id. const uint64_t Version = INSTR_PROF_RAW_VERSION; template inline uint64_t getMagic(); diff --git a/llvm/include/llvm/ProfileData/InstrProfData.inc b/llvm/include/llvm/ProfileData/InstrProfData.inc index bd625457260f59..08a64246962782 100644 --- a/llvm/include/llvm/ProfileData/InstrProfData.inc +++ b/llvm/include/llvm/ProfileData/InstrProfData.inc @@ -137,6 +137,7 @@ INSTR_PROF_RAW_HEADER(uint64_t, NamesSize, NamesSize) INSTR_PROF_RAW_HEADER(uint64_t, CountersDelta, (uintptr_t)CountersBegin) INSTR_PROF_RAW_HEADER(uint64_t, NamesDelta, (uintptr_t)NamesBegin) INSTR_PROF_RAW_HEADER(uint64_t, ValueKindLast, IPVK_Last) +INSTR_PROF_RAW_HEADER(uint64_t, BinaryIdsSize, __llvm_write_binary_ids(NULL)) #undef INSTR_PROF_RAW_HEADER /* INSTR_PROF_RAW_HEADER end */ @@ -645,7 +646,7 @@ serializeValueProfDataFrom(ValueProfRecordClosure *Closure, (uint64_t)'f' << 16 | (uint64_t)'R' << 8 | (uint64_t)129 /* Raw profile format version (start from 1). */ -#define INSTR_PROF_RAW_VERSION 5 +#define INSTR_PROF_RAW_VERSION 6 /* Indexed profile format version (start from 1). */ #define INSTR_PROF_INDEX_VERSION 7 /* Coverage mapping format version (start from 0). */ diff --git a/llvm/include/llvm/ProfileData/InstrProfReader.h b/llvm/include/llvm/ProfileData/InstrProfReader.h index 6746f0c2e55e7d..501c6f011d53ea 100644 --- a/llvm/include/llvm/ProfileData/InstrProfReader.h +++ b/llvm/include/llvm/ProfileData/InstrProfReader.h @@ -82,6 +82,9 @@ class InstrProfReader { /// Read a single record. virtual Error readNextRecord(NamedInstrProfRecord &Record) = 0; + /// Print binary ids on stream OS. + virtual Error printBinaryIds(raw_ostream &OS) { return success(); }; + /// Iterator over profile data. InstrProfIterator begin() { return InstrProfIterator(this); } InstrProfIterator end() { return InstrProfIterator(); } @@ -222,6 +225,9 @@ class RawInstrProfReader : public InstrProfReader { uint32_t ValueKindLast; uint32_t CurValueDataSize; + uint64_t BinaryIdsSize; + const uint8_t *BinaryIdsStart; + public: RawInstrProfReader(std::unique_ptr DataBuffer) : DataBuffer(std::move(DataBuffer)) {} @@ -231,6 +237,7 @@ class RawInstrProfReader : public InstrProfReader { static bool hasFormat(const MemoryBuffer &DataBuffer); Error readHeader() override; Error readNextRecord(NamedInstrProfRecord &Record) override; + Error printBinaryIds(raw_ostream &OS) override; bool isIRLevelProfile() const override { return (Version & VARIANT_MASK_IR_PROF) != 0; diff --git a/llvm/lib/ProfileData/InstrProfReader.cpp b/llvm/lib/ProfileData/InstrProfReader.cpp index fa7610c4200f90..8a4470ae207d59 100644 --- a/llvm/lib/ProfileData/InstrProfReader.cpp +++ b/llvm/lib/ProfileData/InstrProfReader.cpp @@ -24,8 +24,8 @@ #include "llvm/Support/Error.h" #include "llvm/Support/ErrorOr.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/SymbolRemappingReader.h" #include "llvm/Support/SwapByteOrder.h" +#include "llvm/Support/SymbolRemappingReader.h" #include #include #include @@ -374,11 +374,13 @@ Error RawInstrProfReader::readHeader( auto PaddingBytesAfterCounters = swap(Header.PaddingBytesAfterCounters); NamesSize = swap(Header.NamesSize); ValueKindLast = swap(Header.ValueKindLast); + BinaryIdsSize = swap(Header.BinaryIdsSize); auto DataSizeInBytes = DataSize * sizeof(RawInstrProf::ProfileData); auto PaddingSize = getNumPaddingBytes(NamesSize); - ptrdiff_t DataOffset = sizeof(RawInstrProf::Header); + // Profile data starts after profile header and binary ids if exist. + ptrdiff_t DataOffset = sizeof(RawInstrProf::Header) + BinaryIdsSize; ptrdiff_t CountersOffset = DataOffset + DataSizeInBytes + PaddingBytesBeforeCounters; ptrdiff_t NamesOffset = CountersOffset + (sizeof(uint64_t) * CountersSize) + @@ -392,6 +394,10 @@ Error RawInstrProfReader::readHeader( Data = reinterpret_cast *>( Start + DataOffset); DataEnd = Data + DataSize; + + // Binary ids start just after the header. + BinaryIdsStart = + reinterpret_cast(&Header) + sizeof(RawInstrProf::Header); CountersStart = reinterpret_cast(Start + CountersOffset); NamesStart = Start + NamesOffset; ValueDataStart = reinterpret_cast(Start + ValueDataOffset); @@ -506,6 +512,33 @@ Error RawInstrProfReader::readNextRecord(NamedInstrProfRecord &Record) return success(); } +template +Error RawInstrProfReader::printBinaryIds(raw_ostream &OS) { + if (BinaryIdsSize == 0) + return success(); + + OS << "Binary IDs: \n"; + const uint8_t *BI = BinaryIdsStart; + while (BI < BinaryIdsStart + BinaryIdsSize) { + uint64_t BinaryIdLen = swap(*reinterpret_cast(BI)); + // Increment by binary id length data type size. + BI += sizeof(BinaryIdLen); + if (BI > (const uint8_t *)DataBuffer->getBufferEnd()) + return make_error(instrprof_error::malformed); + + for (uint64_t I = 0; I < BinaryIdLen; I++) + OS << format("%02x", BI[I]); + OS << "\n"; + + // Increment by binary id data length. + BI += BinaryIdLen; + if (BI > (const uint8_t *)DataBuffer->getBufferEnd()) + return make_error(instrprof_error::malformed); + } + + return success(); +} + namespace llvm { template class RawInstrProfReader; diff --git a/llvm/test/tools/llvm-profdata/Inputs/c-general.profraw b/llvm/test/tools/llvm-profdata/Inputs/c-general.profraw index c453d806770d82b673e80e0b66f20f73d07ab419..249f22b518e8a7778c7d5101bd85e111665923bd 100644 GIT binary patch delta 539 zcmZ3$+rg*USd^AuRFLzZjR699pfrrCoTw;n8F0t}%;)Ta(2QUng1Fw^Df0W}Z1#(0 zE^`EOSr}mI873#Ph)-6wz&s+GX z`i(;lP#GXK@vO9{^c>GvljMgN6b>Ux{FN59%V=&sxnL&41!RfIx{T7I*Zzm?Xp73+ zmT?40%j8%_<@yiEA_#jJ_@L~sQ*Bwi17d~aFB*mEKbKpRa1_Y|B=s=YD?B}%x%XpC z<%Mey$rCu#Gee{&|7YYBob>9$jHLDt6%Sx)K|wazfJuOp;TY7m$&Sq8lM|Q(csXDq zApMhTnVKiRU=o;of>~g*0J8=YCoEQ+CL6MfE5dk65X%?@p|m25o_vrAXe_J3Sd^AuRFLzZl>q{Hpfrriov0`-$e*hg^Eivf(c(<)v+rik;@MhM0af4d z2~|BOM14I&=#&ag*7>S&Z_j=+jeF^K=Kxg0h0mxO#Gn=wYM!!DYnrtGsrR~xpV_&V z7AQh|6YvdHy)ab0y{}AOLc3!%Gk<>PIf?(TIFumj5BvbBpPa_141ds-4m6&Y6b^`!aEM`9d diff --git a/llvm/test/tools/llvm-profdata/Inputs/compressed.profraw b/llvm/test/tools/llvm-profdata/Inputs/compressed.profraw index dabb8cb4d4c7adfbbe6c927b10c340e315d35758..c096cbff812a42016830f161101255d0f169f5ab 100644 GIT binary patch delta 539 zcmeysbAwm0u_!ISs37M*8v_LJKxr6NIZ;vEGT@K{n9tb-p&7wE1aZB+Q{?x{+3Xk1 zT;>SmvM|8ZGfYlo5uez=;Tm+=G(yZq(52uI!~ld=2#Xggz~XtFMdN63rfrNapSSQ& z^&5vApfW&e;#p}?={cUUCdm&kC>%zX_$w`Hm(kpOa=}c73&;|abs42aul*0((H51t zE#nB1mdUY<%Jm8=wGBr)0RXf!XPE#1 delta 573 zcmcb?`+-NXu_!ISs37M*D+2`ZKxr72J5froERux4-@=Q4-tgv zV1Y84*Rn4C=-ihvtH&mp(MrQg0cyyC22}OjQ1vXH$5}Lv7H4XoeK&I!&(@*}sCtDa zRP~$?_4N#)Qz|rB=c~rOJ^Rfx?xowE15gbG&8Qm0pcWKrp0ZJEnza9^_qvIn*}0Y$ zY=o%$(2A;F7^>dhS0*o^-LaaPKfm*w#Q#?un;_~EIzaT~G)5)Q2~eR6U8qKIK#ll1 z)t1FOAXeD)vz~q!Q^uSNQ1ugfP}OrzzQ`zUE3p}BK_99tGt{)&7tfCrOndEQdx2$U zMD*Tx1E_k2exUlvs!Ynf0Z@?*V3AOuNCZ?wVFE}^D^v4i0cL^83CtXu4VV>}6rG?( j3qolnD6I&kjV3Q-RiAu;m1FV-RtX>t(ke08fNcc;dCPHv diff --git a/llvm/test/tools/llvm-profdata/c-general.test b/llvm/test/tools/llvm-profdata/c-general.test index ae4bc0a34d25cc..7c48f7b04a05c0 100644 --- a/llvm/test/tools/llvm-profdata/c-general.test +++ b/llvm/test/tools/llvm-profdata/c-general.test @@ -14,7 +14,7 @@ RUN: llvm-profdata show %p/Inputs/c-general.profraw -o - --function=switches | F SWITCHES-LABEL: Counters: SWITCHES-NEXT: switches: -SWITCHES-NEXT: Hash: 0xa50a07f391ae4be5 +SWITCHES-NEXT: Hash: 0x0099a0c98383683e SWITCHES-NEXT: Counters: 19 SWITCHES-NEXT: Function count: 1 SWITCHES-LABEL: Functions shown: 1 diff --git a/llvm/test/tools/llvm-profdata/malformed-ptr-to-counter-array.test b/llvm/test/tools/llvm-profdata/malformed-ptr-to-counter-array.test index 5df43f4b9f947d..c60188236f87e2 100644 --- a/llvm/test/tools/llvm-profdata/malformed-ptr-to-counter-array.test +++ b/llvm/test/tools/llvm-profdata/malformed-ptr-to-counter-array.test @@ -8,9 +8,10 @@ // INSTR_PROF_RAW_HEADER(uint64_t, CountersDelta, (uintptr_t)CountersBegin) // INSTR_PROF_RAW_HEADER(uint64_t, NamesDelta, (uintptr_t)NamesBegin) // INSTR_PROF_RAW_HEADER(uint64_t, ValueKindLast, IPVK_Last) +// INSTR_PROF_RAW_HEADER(uint64_t, BinaryIdsSize, __llvm_write_binary_ids(NULL)) RUN: printf '\201rforpl\377' > %t.profraw -RUN: printf '\5\0\0\0\0\0\0\0' >> %t.profraw +RUN: printf '\6\0\0\0\0\0\0\0' >> %t.profraw RUN: printf '\1\0\0\0\0\0\0\0' >> %t.profraw RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw RUN: printf '\2\0\0\0\0\0\0\0' >> %t.profraw @@ -19,6 +20,7 @@ RUN: printf '\10\0\0\0\0\0\0\0' >> %t.profraw RUN: printf '\0\0\6\0\1\0\0\0' >> %t.profraw RUN: printf '\0\0\6\0\2\0\0\0' >> %t.profraw RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw +RUN: printf '\0\0\0\0\0\0\0\0' >> %t.profraw // Data Section // diff --git a/llvm/test/tools/llvm-profdata/raw-32-bits-be.test b/llvm/test/tools/llvm-profdata/raw-32-bits-be.test index cebd25a07f4a1b..3f8e8427da3e07 100644 --- a/llvm/test/tools/llvm-profdata/raw-32-bits-be.test +++ b/llvm/test/tools/llvm-profdata/raw-32-bits-be.test @@ -1,5 +1,5 @@ RUN: printf '\377lprofR\201' > %t -RUN: printf '\0\0\0\0\0\0\0\5' >> %t +RUN: printf '\0\0\0\0\0\0\0\6' >> %t RUN: printf '\0\0\0\0\0\0\0\2' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\3' >> %t @@ -8,6 +8,7 @@ RUN: printf '\0\0\0\0\0\0\0\20' >> %t RUN: printf '\0\0\0\0\1\0\0\0' >> %t RUN: printf '\0\0\0\0\2\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t +RUN: printf '\0\0\0\0\0\0\0\0' >> %t RUN: printf '\134\370\302\114\333\030\275\254' >> %t RUN: printf '\0\0\0\0\0\0\0\1' >> %t diff --git a/llvm/test/tools/llvm-profdata/raw-32-bits-le.test b/llvm/test/tools/llvm-profdata/raw-32-bits-le.test index a176f80ec95ac2..04a6e817543594 100644 --- a/llvm/test/tools/llvm-profdata/raw-32-bits-le.test +++ b/llvm/test/tools/llvm-profdata/raw-32-bits-le.test @@ -1,5 +1,5 @@ RUN: printf '\201Rforpl\377' > %t -RUN: printf '\5\0\0\0\0\0\0\0' >> %t +RUN: printf '\6\0\0\0\0\0\0\0' >> %t RUN: printf '\2\0\0\0\0\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t RUN: printf '\3\0\0\0\0\0\0\0' >> %t @@ -8,6 +8,7 @@ RUN: printf '\20\0\0\0\0\0\0\0' >> %t RUN: printf '\0\0\0\1\0\0\0\0' >> %t RUN: printf '\0\0\0\2\0\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t +RUN: printf '\0\0\0\0\0\0\0\0' >> %t RUN: printf '\254\275\030\333\114\302\370\134' >> %t RUN: printf '\1\0\0\0\0\0\0\0' >> %t diff --git a/llvm/test/tools/llvm-profdata/raw-64-bits-be.test b/llvm/test/tools/llvm-profdata/raw-64-bits-be.test index c679207102e401..ec624ea4be223e 100644 --- a/llvm/test/tools/llvm-profdata/raw-64-bits-be.test +++ b/llvm/test/tools/llvm-profdata/raw-64-bits-be.test @@ -1,5 +1,5 @@ RUN: printf '\377lprofr\201' > %t -RUN: printf '\0\0\0\0\0\0\0\5' >> %t +RUN: printf '\0\0\0\0\0\0\0\6' >> %t RUN: printf '\0\0\0\0\0\0\0\2' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\3' >> %t @@ -8,6 +8,7 @@ RUN: printf '\0\0\0\0\0\0\0\20' >> %t RUN: printf '\0\0\0\1\0\4\0\0' >> %t RUN: printf '\0\0\0\2\0\4\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t +RUN: printf '\0\0\0\0\0\0\0\0' >> %t RUN: printf '\134\370\302\114\333\030\275\254' >> %t RUN: printf '\0\0\0\0\0\0\0\1' >> %t diff --git a/llvm/test/tools/llvm-profdata/raw-64-bits-le.test b/llvm/test/tools/llvm-profdata/raw-64-bits-le.test index 8e179a87162558..80564458d37fa0 100644 --- a/llvm/test/tools/llvm-profdata/raw-64-bits-le.test +++ b/llvm/test/tools/llvm-profdata/raw-64-bits-le.test @@ -1,5 +1,5 @@ RUN: printf '\201rforpl\377' > %t -RUN: printf '\5\0\0\0\0\0\0\0' >> %t +RUN: printf '\6\0\0\0\0\0\0\0' >> %t RUN: printf '\2\0\0\0\0\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t RUN: printf '\3\0\0\0\0\0\0\0' >> %t @@ -8,6 +8,7 @@ RUN: printf '\20\0\0\0\0\0\0\0' >> %t RUN: printf '\0\0\4\0\1\0\0\0' >> %t RUN: printf '\0\0\4\0\2\0\0\0' >> %t RUN: printf '\0\0\0\0\0\0\0\0' >> %t +RUN: printf '\0\0\0\0\0\0\0\0' >> %t RUN: printf '\254\275\030\333\114\302\370\134' >> %t RUN: printf '\1\0\0\0\0\0\0\0' >> %t diff --git a/llvm/test/tools/llvm-profdata/raw-two-profiles.test b/llvm/test/tools/llvm-profdata/raw-two-profiles.test index 9cd8a8c7b00ee2..a4f97a582d20d0 100644 --- a/llvm/test/tools/llvm-profdata/raw-two-profiles.test +++ b/llvm/test/tools/llvm-profdata/raw-two-profiles.test @@ -1,5 +1,5 @@ RUN: printf '\201rforpl\377' > %t-foo.profraw -RUN: printf '\5\0\0\0\0\0\0\0' >> %t-foo.profraw +RUN: printf '\6\0\0\0\0\0\0\0' >> %t-foo.profraw RUN: printf '\1\0\0\0\0\0\0\0' >> %t-foo.profraw RUN: printf '\0\0\0\0\0\0\0\0' >> %t-foo.profraw RUN: printf '\1\0\0\0\0\0\0\0' >> %t-foo.profraw @@ -8,6 +8,7 @@ RUN: printf '\10\0\0\0\0\0\0\0' >> %t-foo.profraw RUN: printf '\0\0\4\0\1\0\0\0' >> %t-foo.profraw RUN: printf '\0\0\4\0\2\0\0\0' >> %t-foo.profraw RUN: printf '\0\0\0\0\0\0\0\0' >> %t-foo.profraw +RUN: printf '\0\0\0\0\0\0\0\0' >> %t-foo.profraw RUN: printf '\254\275\030\333\114\302\370\134' >> %t-foo.profraw RUN: printf '\1\0\0\0\0\0\0\0' >> %t-foo.profraw @@ -20,7 +21,7 @@ RUN: printf '\023\0\0\0\0\0\0\0' >> %t-foo.profraw RUN: printf '\3\0foo\0\0\0' >> %t-foo.profraw RUN: printf '\201rforpl\377' > %t-bar.profraw -RUN: printf '\5\0\0\0\0\0\0\0' >> %t-bar.profraw +RUN: printf '\6\0\0\0\0\0\0\0' >> %t-bar.profraw RUN: printf '\1\0\0\0\0\0\0\0' >> %t-bar.profraw RUN: printf '\0\0\0\0\0\0\0\0' >> %t-bar.profraw RUN: printf '\2\0\0\0\0\0\0\0' >> %t-bar.profraw @@ -29,6 +30,7 @@ RUN: printf '\10\0\0\0\0\0\0\0' >> %t-bar.profraw RUN: printf '\0\0\6\0\1\0\0\0' >> %t-bar.profraw RUN: printf '\0\0\6\0\2\0\0\0' >> %t-bar.profraw RUN: printf '\0\0\0\0\0\0\0\0' >> %t-bar.profraw +RUN: printf '\0\0\0\0\0\0\0\0' >> %t-bar.profraw RUN: printf '\067\265\035\031\112\165\023\344' >> %t-bar.profraw RUN: printf '\02\0\0\0\0\0\0\0' >> %t-bar.profraw diff --git a/llvm/tools/llvm-profdata/llvm-profdata.cpp b/llvm/tools/llvm-profdata/llvm-profdata.cpp index b61df6eacdce55..66d70120ac9b68 100644 --- a/llvm/tools/llvm-profdata/llvm-profdata.cpp +++ b/llvm/tools/llvm-profdata/llvm-profdata.cpp @@ -2069,7 +2069,7 @@ static int showInstrProfile(const std::string &Filename, bool ShowCounts, bool ShowAllFunctions, bool ShowCS, uint64_t ValueCutoff, bool OnlyListBelow, const std::string &ShowFunction, bool TextFormat, - raw_fd_ostream &OS) { + bool ShowBinaryIds, raw_fd_ostream &OS) { auto ReaderOrErr = InstrProfReader::create(Filename); std::vector Cutoffs = std::move(DetailedSummaryCutoffs); if (ShowDetailedSummary && Cutoffs.empty()) { @@ -2251,6 +2251,11 @@ static int showInstrProfile(const std::string &Filename, bool ShowCounts, OS << "Total count: " << PS->getTotalCount() << "\n"; PS->printDetailedSummary(OS); } + + if (ShowBinaryIds) + if (Error E = Reader->printBinaryIds(OS)) + exitWithError(std::move(E), Filename); + return 0; } @@ -2501,6 +2506,8 @@ static int show_main(int argc, const char *argv[]) { cl::desc("Show the information of each section in the sample profile. " "The flag is only usable when the sample profile is in " "extbinary format")); + cl::opt ShowBinaryIds("binary-ids", cl::init(false), + cl::desc("Show binary ids in the profile. ")); cl::ParseCommandLineOptions(argc, argv, "LLVM profile data summary\n"); @@ -2519,11 +2526,11 @@ static int show_main(int argc, const char *argv[]) { WithColor::warning() << "-function argument ignored: showing all functions\n"; if (ProfileKind == instr) - return showInstrProfile(Filename, ShowCounts, TopNFunctions, - ShowIndirectCallTargets, ShowMemOPSizes, - ShowDetailedSummary, DetailedSummaryCutoffs, - ShowAllFunctions, ShowCS, ValueCutoff, - OnlyListBelow, ShowFunction, TextFormat, OS); + return showInstrProfile( + Filename, ShowCounts, TopNFunctions, ShowIndirectCallTargets, + ShowMemOPSizes, ShowDetailedSummary, DetailedSummaryCutoffs, + ShowAllFunctions, ShowCS, ValueCutoff, OnlyListBelow, ShowFunction, + TextFormat, ShowBinaryIds, OS); else return showSampleProfile(Filename, ShowCounts, ShowAllFunctions, ShowDetailedSummary, ShowFunction,