Skip to content

Commit b9951b3

Browse files
authored
[llvm-profdata] Fix binary ids with multiple raw profiles in a single… (#72740)
Save binary ids when iterating through `RawInstrProfReader`. Fixes #72699.
1 parent 0ba5f6e commit b9951b3

File tree

3 files changed

+68
-38
lines changed

3 files changed

+68
-38
lines changed

compiler-rt/test/profile/Linux/binary-id.c

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,35 @@
1717
// RUN: llvm-profdata show --binary-ids %t.profdir/default_*.profraw > %t.profraw.out
1818
// RUN: FileCheck %s --check-prefix=BINARY-ID-MERGE-PROF < %t.profraw.out
1919

20-
// RUN: llvm-profdata merge -o %t.profdata %t.profraw %t.profraw
20+
// RUN: llvm-profdata merge -o %t.profdata %t.profdir/default_*.profraw
2121
// RUN: llvm-profdata show --binary-ids %t.profdata > %t.profdata.out
22-
// RUN: FileCheck %s --check-prefix=BINARY-ID-INDEXED-PROF < %t.profraw.out
22+
// RUN: FileCheck %s --check-prefix=BINARY-ID-INDEXED-PROF < %t.profdata.out
2323

24+
// Test raw profiles with shared libraries.
25+
// RUN: split-file %s %t.dir
26+
// RUN: %clang_profgen -Wl,--build-id -fpic -shared -O2 %t.dir/foo.c -o %t.dir/libfoo.so
27+
// RUN: %clang_profgen -Wl,--build-id -fpic -shared -O2 %t.dir/bar.c -o %t.dir/libbar.so
28+
// RUN: %clang_profgen -Wl,--build-id -O2 %t.dir/main.c %t.dir/libfoo.so %t.dir/libbar.so -o %t
29+
// RUN: env LLVM_PROFILE_FILE=%t.profraw LD_LIBRARY_PATH=%t.dir %run %t
30+
// RUN: llvm-profdata show --binary-ids %t.profraw > %t.profraw.out
31+
// RUN: llvm-profdata merge -o %t.profdata %t.profraw
32+
// RUN: FileCheck %s --check-prefix=BINARY-ID-SHARE-RAW-PROF < %t.profraw.out
33+
34+
// RUN: llvm-profdata merge -o %t.profdata %t.profraw
35+
// RUN: llvm-profdata show --binary-ids %t.profdata > %t.profdata.out
36+
// RUN: FileCheck %s --check-prefix=BINARY-ID-SHARE-INDEXED-PROF < %t.profraw.out
37+
38+
//--- foo.c
2439
void foo() {
2540
}
2641

42+
//--- bar.c
2743
void bar() {
2844
}
2945

46+
//--- main.c
47+
void foo();
48+
void bar();
3049
int main() {
3150
foo();
3251
bar();
@@ -59,3 +78,21 @@ int main() {
5978
// BINARY-ID-INDEXED-PROF-NEXT: Maximum internal block count: 0
6079
// BINARY-ID-INDEXED-PROF-NEXT: Binary IDs:
6180
// BINARY-ID-INDEXED-PROF-NEXT: {{[0-9a-f]+}}
81+
82+
// BINARY-ID-SHARE-RAW-PROF: Instrumentation level: Front-end
83+
// BINARY-ID-SHARE-RAW-PROF-NEXT: Total functions: 3
84+
// BINARY-ID-SHARE-RAW-PROF-NEXT: Maximum function count: 1
85+
// BINARY-ID-SHARE-RAW-PROF-NEXT: Maximum internal block count: 0
86+
// BINARY-ID-SHARE-RAW-PROF-NEXT: Binary IDs:
87+
// BINARY-ID-SHARE-RAW-PROF-NEXT: {{[0-9a-f]+}}
88+
// BINARY-ID-SHARE-RAW-PROF-NEXT: {{[0-9a-f]+}}
89+
// BINARY-ID-SHARE-RAW-PROF-NEXT: {{[0-9a-f]+}}
90+
91+
// BINARY-ID-SHARE-INDEXED-PROF: Instrumentation level: Front-end
92+
// BINARY-ID-SHARE-INDEXED-PROF-NEXT: Total functions: 3
93+
// BINARY-ID-SHARE-INDEXED-PROF-NEXT: Maximum function count: 1
94+
// BINARY-ID-SHARE-INDEXED-PROF-NEXT: Maximum internal block count: 0
95+
// BINARY-ID-SHARE-INDEXED-PROF-NEXT: Binary IDs:
96+
// BINARY-ID-SHARE-INDEXED-PROF-NEXT: {{[0-9a-f]+}}
97+
// BINARY-ID-SHARE-INDEXED-PROF-NEXT: {{[0-9a-f]+}}
98+
// BINARY-ID-SHARE-INDEXED-PROF-NEXT: {{[0-9a-f]+}}

llvm/include/llvm/ProfileData/InstrProfReader.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -340,11 +340,7 @@ class RawInstrProfReader : public InstrProfReader {
340340
const uint8_t *ValueDataStart;
341341
uint32_t ValueKindLast;
342342
uint32_t CurValueDataSize;
343-
344-
/// Total size of binary ids.
345-
uint64_t BinaryIdsSize{0};
346-
/// Start address of binary id length and data pairs.
347-
const uint8_t *BinaryIdsStart;
343+
std::vector<llvm::object::BuildID> BinaryIds;
348344

349345
std::function<void(Error)> Warn;
350346

llvm/lib/ProfileData/InstrProfReader.cpp

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -142,27 +142,15 @@ readBinaryIdsInternal(const MemoryBuffer &DataBuffer,
142142
return Error::success();
143143
}
144144

145-
static Error printBinaryIdsInternal(raw_ostream &OS,
146-
const MemoryBuffer &DataBuffer,
147-
uint64_t BinaryIdsSize,
148-
const uint8_t *BinaryIdsStart,
149-
llvm::endianness Endian) {
150-
if (BinaryIdsSize == 0)
151-
return Error::success();
152-
153-
std::vector<llvm::object::BuildID> BinaryIds;
154-
if (Error E = readBinaryIdsInternal(DataBuffer, BinaryIdsSize, BinaryIdsStart,
155-
BinaryIds, Endian))
156-
return E;
157-
145+
static void
146+
printBinaryIdsInternal(raw_ostream &OS,
147+
std::vector<llvm::object::BuildID> &BinaryIds) {
158148
OS << "Binary IDs: \n";
159149
for (auto BI : BinaryIds) {
160150
for (uint64_t I = 0; I < BI.size(); I++)
161151
OS << format("%02x", BI[I]);
162152
OS << "\n";
163153
}
164-
165-
return Error::success();
166154
}
167155

168156
Expected<std::unique_ptr<InstrProfReader>>
@@ -573,9 +561,20 @@ Error RawInstrProfReader<IntPtrT>::readHeader(
573561
if (!useCorrelate() && Correlator)
574562
return error(instrprof_error::unexpected_debug_info_for_correlation);
575563

576-
BinaryIdsSize = swap(Header.BinaryIdsSize);
577-
if (BinaryIdsSize % sizeof(uint64_t))
564+
uint64_t BinaryIdSize = swap(Header.BinaryIdsSize);
565+
// Binary id start just after the header if exists.
566+
const uint8_t *BinaryIdStart =
567+
reinterpret_cast<const uint8_t *>(&Header) + sizeof(RawInstrProf::Header);
568+
const uint8_t *BinaryIdEnd = BinaryIdStart + BinaryIdSize;
569+
const uint8_t *BufferEnd = (const uint8_t *)DataBuffer->getBufferEnd();
570+
if (BinaryIdSize % sizeof(uint64_t) || BinaryIdEnd > BufferEnd)
578571
return error(instrprof_error::bad_header);
572+
if (BinaryIdSize != 0) {
573+
if (Error Err =
574+
readBinaryIdsInternal(*DataBuffer, BinaryIdSize, BinaryIdStart,
575+
BinaryIds, getDataEndianness()))
576+
return Err;
577+
}
579578

580579
CountersDelta = swap(Header.CountersDelta);
581580
BitmapDelta = swap(Header.BitmapDelta);
@@ -593,7 +592,7 @@ Error RawInstrProfReader<IntPtrT>::readHeader(
593592
auto PaddingSize = getNumPaddingBytes(NamesSize);
594593

595594
// Profile data starts after profile header and binary ids if exist.
596-
ptrdiff_t DataOffset = sizeof(RawInstrProf::Header) + BinaryIdsSize;
595+
ptrdiff_t DataOffset = sizeof(RawInstrProf::Header) + BinaryIdSize;
597596
ptrdiff_t CountersOffset = DataOffset + DataSize + PaddingBytesBeforeCounters;
598597
ptrdiff_t BitmapOffset =
599598
CountersOffset + CountersSize + PaddingBytesAfterCounters;
@@ -622,19 +621,12 @@ Error RawInstrProfReader<IntPtrT>::readHeader(
622621
NamesEnd = NamesStart + NamesSize;
623622
}
624623

625-
// Binary ids start just after the header.
626-
BinaryIdsStart =
627-
reinterpret_cast<const uint8_t *>(&Header) + sizeof(RawInstrProf::Header);
628624
CountersStart = Start + CountersOffset;
629625
CountersEnd = CountersStart + CountersSize;
630626
BitmapStart = Start + BitmapOffset;
631627
BitmapEnd = BitmapStart + NumBitmapBytes;
632628
ValueDataStart = reinterpret_cast<const uint8_t *>(Start + ValueDataOffset);
633629

634-
const uint8_t *BufferEnd = (const uint8_t *)DataBuffer->getBufferEnd();
635-
if (BinaryIdsStart + BinaryIdsSize > BufferEnd)
636-
return error(instrprof_error::bad_header);
637-
638630
std::unique_ptr<InstrProfSymtab> NewSymtab = std::make_unique<InstrProfSymtab>();
639631
if (Error E = createSymtab(*NewSymtab))
640632
return E;
@@ -832,14 +824,16 @@ Error RawInstrProfReader<IntPtrT>::readNextRecord(NamedInstrProfRecord &Record)
832824
template <class IntPtrT>
833825
Error RawInstrProfReader<IntPtrT>::readBinaryIds(
834826
std::vector<llvm::object::BuildID> &BinaryIds) {
835-
return readBinaryIdsInternal(*DataBuffer, BinaryIdsSize, BinaryIdsStart,
836-
BinaryIds, getDataEndianness());
827+
BinaryIds.insert(BinaryIds.begin(), this->BinaryIds.begin(),
828+
this->BinaryIds.end());
829+
return Error::success();
837830
}
838831

839832
template <class IntPtrT>
840833
Error RawInstrProfReader<IntPtrT>::printBinaryIds(raw_ostream &OS) {
841-
return printBinaryIdsInternal(OS, *DataBuffer, BinaryIdsSize, BinaryIdsStart,
842-
getDataEndianness());
834+
if (!BinaryIds.empty())
835+
printBinaryIdsInternal(OS, BinaryIds);
836+
return Error::success();
843837
}
844838

845839
namespace llvm {
@@ -1475,8 +1469,11 @@ Error IndexedInstrProfReader::readBinaryIds(
14751469
}
14761470

14771471
Error IndexedInstrProfReader::printBinaryIds(raw_ostream &OS) {
1478-
return printBinaryIdsInternal(OS, *DataBuffer, BinaryIdsSize, BinaryIdsStart,
1479-
llvm::endianness::little);
1472+
std::vector<llvm::object::BuildID> BinaryIds;
1473+
if (Error E = readBinaryIds(BinaryIds))
1474+
return E;
1475+
printBinaryIdsInternal(OS, BinaryIds);
1476+
return Error::success();
14801477
}
14811478

14821479
void InstrProfReader::accumulateCounts(CountSumOrPercent &Sum, bool IsCS) {

0 commit comments

Comments
 (0)