Skip to content

Commit 3c97c8b

Browse files
authored
[Profile] Refactor profile correlation. (llvm#70856)
Refactor some code from llvm#69493. llvm#70712 was reverted due to linking failures. So, `-debug-info-correlate` remains unchanged and no new flag added.
1 parent 8b61ef0 commit 3c97c8b

File tree

11 files changed

+121
-62
lines changed

11 files changed

+121
-62
lines changed

compiler-rt/lib/profile/InstrProfiling.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,3 +89,7 @@ COMPILER_RT_VISIBILITY void __llvm_profile_reset_counters(void) {
8989
}
9090
lprofSetProfileDumped(0);
9191
}
92+
93+
inline int hasCorrelation() {
94+
return (__llvm_profile_get_version() & VARIANT_MASK_DBG_CORRELATE) != 0ULL;
95+
}

compiler-rt/lib/profile/InstrProfiling.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,9 @@ uint64_t __llvm_profile_get_magic(void);
261261
/*! \brief Get the version of the file format. */
262262
uint64_t __llvm_profile_get_version(void);
263263

264+
/*! \brief If the binary is compiled with profile correlation. */
265+
int hasCorrelation();
266+
264267
/*! \brief Get the number of entries in the profile data section. */
265268
uint64_t __llvm_profile_get_num_data(const __llvm_profile_data *Begin,
266269
const __llvm_profile_data *End);
@@ -282,6 +285,9 @@ uint64_t __llvm_profile_get_counters_size(const char *Begin, const char *End);
282285
uint64_t __llvm_profile_get_num_bitmap_bytes(const char *Begin,
283286
const char *End);
284287

288+
/*! \brief Get the size of the profile name section in bytes. */
289+
uint64_t __llvm_profile_get_name_size(const char *Begin, const char *End);
290+
285291
/* ! \brief Given the sizes of the data and counter information, return the
286292
* number of padding bytes before and after the counters, and after the names,
287293
* in the raw profile.

compiler-rt/lib/profile/InstrProfilingBuffer.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ uint64_t __llvm_profile_get_size_for_buffer(void) {
5656
COMPILER_RT_VISIBILITY
5757
uint64_t __llvm_profile_get_num_data(const __llvm_profile_data *Begin,
5858
const __llvm_profile_data *End) {
59+
if (hasCorrelation())
60+
return 0;
5961
intptr_t BeginI = (intptr_t)Begin, EndI = (intptr_t)End;
6062
return ((EndI + sizeof(__llvm_profile_data) - 1) - BeginI) /
6163
sizeof(__llvm_profile_data);
@@ -64,6 +66,8 @@ uint64_t __llvm_profile_get_num_data(const __llvm_profile_data *Begin,
6466
COMPILER_RT_VISIBILITY
6567
uint64_t __llvm_profile_get_data_size(const __llvm_profile_data *Begin,
6668
const __llvm_profile_data *End) {
69+
if (hasCorrelation())
70+
return 0;
6771
return __llvm_profile_get_num_data(Begin, End) * sizeof(__llvm_profile_data);
6872
}
6973

@@ -92,6 +96,13 @@ uint64_t __llvm_profile_get_num_bitmap_bytes(const char *Begin,
9296
return (End - Begin);
9397
}
9498

99+
COMPILER_RT_VISIBILITY
100+
uint64_t __llvm_profile_get_name_size(const char *Begin, const char *End) {
101+
if (hasCorrelation())
102+
return 0;
103+
return End - Begin;
104+
}
105+
95106
/// Calculate the number of padding bytes needed to add to \p Offset in order
96107
/// for (\p Offset + Padding) to be page-aligned.
97108
static uint64_t calculateBytesNeededToPageAlign(uint64_t Offset) {

compiler-rt/lib/profile/InstrProfilingMerge.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,9 @@ int __llvm_profile_check_compatibility(const char *ProfileData,
6969
Header->NumBitmapBytes !=
7070
__llvm_profile_get_num_bitmap_bytes(__llvm_profile_begin_bitmap(),
7171
__llvm_profile_end_bitmap()) ||
72-
Header->NamesSize != (uint64_t)(__llvm_profile_end_names() -
73-
__llvm_profile_begin_names()) ||
72+
Header->NamesSize !=
73+
__llvm_profile_get_name_size(__llvm_profile_begin_names(),
74+
__llvm_profile_end_names()) ||
7475
Header->ValueKindLast != IPVK_Last)
7576
return 1;
7677

@@ -138,9 +139,9 @@ int __llvm_profile_merge_from_buffer(const char *ProfileData,
138139
if (SrcNameStart < SrcCountersStart || SrcNameStart < SrcBitmapStart)
139140
return 1;
140141

141-
// Merge counters by iterating the entire counter section when debug info
142-
// correlation is enabled.
143-
if (__llvm_profile_get_version() & VARIANT_MASK_DBG_CORRELATE) {
142+
// Merge counters by iterating the entire counter section when correlation is
143+
// enabled.
144+
if (hasCorrelation()) {
144145
for (SrcCounter = SrcCountersStart,
145146
DstCounter = __llvm_profile_begin_counters();
146147
SrcCounter < SrcCountersEnd;) {

compiler-rt/lib/profile/InstrProfilingWriter.c

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -262,21 +262,19 @@ lprofWriteDataImpl(ProfDataWriter *Writer, const __llvm_profile_data *DataBegin,
262262
const char *BitmapBegin, const char *BitmapEnd,
263263
VPDataReaderType *VPDataReader, const char *NamesBegin,
264264
const char *NamesEnd, int SkipNameDataWrite) {
265-
int DebugInfoCorrelate =
266-
(__llvm_profile_get_version() & VARIANT_MASK_DBG_CORRELATE) != 0ULL;
265+
int ProfileCorrelation = hasCorrelation();
267266

268267
/* Calculate size of sections. */
269268
const uint64_t DataSectionSize =
270-
DebugInfoCorrelate ? 0 : __llvm_profile_get_data_size(DataBegin, DataEnd);
271-
const uint64_t NumData =
272-
DebugInfoCorrelate ? 0 : __llvm_profile_get_num_data(DataBegin, DataEnd);
269+
__llvm_profile_get_data_size(DataBegin, DataEnd);
270+
const uint64_t NumData = __llvm_profile_get_num_data(DataBegin, DataEnd);
273271
const uint64_t CountersSectionSize =
274272
__llvm_profile_get_counters_size(CountersBegin, CountersEnd);
275273
const uint64_t NumCounters =
276274
__llvm_profile_get_num_counters(CountersBegin, CountersEnd);
277275
const uint64_t NumBitmapBytes =
278276
__llvm_profile_get_num_bitmap_bytes(BitmapBegin, BitmapEnd);
279-
const uint64_t NamesSize = DebugInfoCorrelate ? 0 : NamesEnd - NamesBegin;
277+
const uint64_t NamesSize = __llvm_profile_get_name_size(NamesBegin, NamesEnd);
280278

281279
/* Create the header. */
282280
__llvm_profile_header Header;
@@ -304,7 +302,7 @@ lprofWriteDataImpl(ProfDataWriter *Writer, const __llvm_profile_data *DataBegin,
304302
#endif
305303

306304
/* The data and names sections are omitted in lightweight mode. */
307-
if (DebugInfoCorrelate) {
305+
if (ProfileCorrelation) {
308306
Header.CountersDelta = 0;
309307
Header.NamesDelta = 0;
310308
}
@@ -320,21 +318,22 @@ lprofWriteDataImpl(ProfDataWriter *Writer, const __llvm_profile_data *DataBegin,
320318

321319
/* Write the profile data. */
322320
ProfDataIOVec IOVecData[] = {
323-
{DebugInfoCorrelate ? NULL : DataBegin, sizeof(uint8_t), DataSectionSize,
321+
{ProfileCorrelation ? NULL : DataBegin, sizeof(uint8_t), DataSectionSize,
324322
0},
325323
{NULL, sizeof(uint8_t), PaddingBytesBeforeCounters, 1},
326324
{CountersBegin, sizeof(uint8_t), CountersSectionSize, 0},
327325
{NULL, sizeof(uint8_t), PaddingBytesAfterCounters, 1},
328326
{BitmapBegin, sizeof(uint8_t), NumBitmapBytes, 0},
329327
{NULL, sizeof(uint8_t), PaddingBytesAfterBitmapBytes, 1},
330-
{(SkipNameDataWrite || DebugInfoCorrelate) ? NULL : NamesBegin,
328+
{(SkipNameDataWrite || ProfileCorrelation) ? NULL : NamesBegin,
331329
sizeof(uint8_t), NamesSize, 0},
332330
{NULL, sizeof(uint8_t), PaddingBytesAfterNames, 1}};
333331
if (Writer->Write(Writer, IOVecData, sizeof(IOVecData) / sizeof(*IOVecData)))
334332
return -1;
335333

336-
/* Value profiling is not yet supported in continuous mode. */
337-
if (__llvm_profile_is_continuous_mode_enabled())
334+
/* Value profiling is not yet supported in continuous mode and profile
335+
* correlation mode. */
336+
if (__llvm_profile_is_continuous_mode_enabled() || ProfileCorrelation)
338337
return 0;
339338

340339
return writeValueProfData(Writer, VPDataReader, DataBegin, DataEnd);

compiler-rt/test/profile/Linux/instrprof-show-debug-info-correlation.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
// RUN: %clang_pgogen -o %t.no.dbg -mllvm --debug-info-correlate -mllvm --disable-vp=true %s
66
// RUN: not llvm-profdata show --debug-info=%t.no.dbg 2>&1 | FileCheck %s --check-prefix NO-DBG
7-
// NO-DBG: unable to correlate profile: could not find any profile metadata in debug info
7+
// NO-DBG: unable to correlate profile: could not find any profile data metadata in correlated file
88

99
// YAML: Probes:
1010
// YAML: - Function Name: a

llvm/include/llvm/ProfileData/InstrProfCorrelator.h

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,11 @@ class ObjectFile;
3131
/// to their functions.
3232
class InstrProfCorrelator {
3333
public:
34+
/// Indicate which kind correlator to use.
35+
enum ProfCorrelatorKind { NONE, DEBUG_INFO };
36+
3437
static llvm::Expected<std::unique_ptr<InstrProfCorrelator>>
35-
get(StringRef DebugInfoFilename);
38+
get(StringRef Filename, ProfCorrelatorKind FileKind);
3639

3740
/// Construct a ProfileData vector used to correlate raw instrumentation data
3841
/// to their functions.
@@ -104,7 +107,7 @@ class InstrProfCorrelator {
104107

105108
private:
106109
static llvm::Expected<std::unique_ptr<InstrProfCorrelator>>
107-
get(std::unique_ptr<MemoryBuffer> Buffer);
110+
get(std::unique_ptr<MemoryBuffer> Buffer, ProfCorrelatorKind FileKind);
108111

109112
const InstrProfCorrelatorKind Kind;
110113
};
@@ -128,7 +131,7 @@ class InstrProfCorrelatorImpl : public InstrProfCorrelator {
128131

129132
static llvm::Expected<std::unique_ptr<InstrProfCorrelatorImpl<IntPtrT>>>
130133
get(std::unique_ptr<InstrProfCorrelator::Context> Ctx,
131-
const object::ObjectFile &Obj);
134+
const object::ObjectFile &Obj, ProfCorrelatorKind FileKind);
132135

133136
protected:
134137
std::vector<RawInstrProf::ProfileData<IntPtrT>> Data;
@@ -138,6 +141,8 @@ class InstrProfCorrelatorImpl : public InstrProfCorrelator {
138141
int MaxWarnings,
139142
InstrProfCorrelator::CorrelationData *Data = nullptr) = 0;
140143

144+
virtual Error correlateProfileNameImpl() = 0;
145+
141146
Error dumpYaml(int MaxWarnings, raw_ostream &OS) override;
142147

143148
void addProbe(StringRef FunctionName, uint64_t CFGHash, IntPtrT CounterOffset,
@@ -205,6 +210,8 @@ class DwarfInstrProfCorrelator : public InstrProfCorrelatorImpl<IntPtrT> {
205210
void correlateProfileDataImpl(
206211
int MaxWarnings,
207212
InstrProfCorrelator::CorrelationData *Data = nullptr) override;
213+
214+
Error correlateProfileNameImpl() override;
208215
};
209216

210217
} // end namespace llvm

llvm/include/llvm/ProfileData/InstrProfReader.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -386,6 +386,8 @@ class RawInstrProfReader : public InstrProfReader {
386386
return (Version & VARIANT_MASK_DBG_CORRELATE) != 0;
387387
}
388388

389+
bool useCorrelate() const { return useDebugInfoCorrelate(); }
390+
389391
bool hasSingleByteCoverage() const override {
390392
return (Version & VARIANT_MASK_BYTE_COVERAGE) != 0;
391393
}

llvm/lib/ProfileData/InstrProfCorrelator.cpp

Lines changed: 63 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,20 @@
2424

2525
using namespace llvm;
2626

27-
/// Get the __llvm_prf_cnts section.
28-
Expected<object::SectionRef> getCountersSection(const object::ObjectFile &Obj) {
27+
/// Get profile section.
28+
Expected<object::SectionRef> getInstrProfSection(const object::ObjectFile &Obj,
29+
InstrProfSectKind IPSK) {
30+
Triple::ObjectFormatType ObjFormat = Obj.getTripleObjectFormat();
31+
std::string ExpectedSectionName =
32+
getInstrProfSectionName(IPSK, ObjFormat,
33+
/*AddSegmentInfo=*/false);
2934
for (auto &Section : Obj.sections())
3035
if (auto SectionName = Section.getName())
31-
if (SectionName.get() == INSTR_PROF_CNTS_SECT_NAME)
36+
if (SectionName.get() == ExpectedSectionName)
3237
return Section;
3338
return make_error<InstrProfError>(
3439
instrprof_error::unable_to_correlate_profile,
35-
"could not find counter section (" INSTR_PROF_CNTS_SECT_NAME ")");
40+
"could not find section (" + Twine(ExpectedSectionName) + ")");
3641
}
3742

3843
const char *InstrProfCorrelator::FunctionNameAttributeName = "Function Name";
@@ -42,7 +47,7 @@ const char *InstrProfCorrelator::NumCountersAttributeName = "Num Counters";
4247
llvm::Expected<std::unique_ptr<InstrProfCorrelator::Context>>
4348
InstrProfCorrelator::Context::get(std::unique_ptr<MemoryBuffer> Buffer,
4449
const object::ObjectFile &Obj) {
45-
auto CountersSection = getCountersSection(Obj);
50+
auto CountersSection = getInstrProfSection(Obj, IPSK_cnts);
4651
if (auto Err = CountersSection.takeError())
4752
return std::move(Err);
4853
auto C = std::make_unique<Context>();
@@ -54,30 +59,32 @@ InstrProfCorrelator::Context::get(std::unique_ptr<MemoryBuffer> Buffer,
5459
}
5560

5661
llvm::Expected<std::unique_ptr<InstrProfCorrelator>>
57-
InstrProfCorrelator::get(StringRef DebugInfoFilename) {
58-
auto DsymObjectsOrErr =
59-
object::MachOObjectFile::findDsymObjectMembers(DebugInfoFilename);
60-
if (auto Err = DsymObjectsOrErr.takeError())
61-
return std::move(Err);
62-
if (!DsymObjectsOrErr->empty()) {
63-
// TODO: Enable profile correlation when there are multiple objects in a
64-
// dSYM bundle.
65-
if (DsymObjectsOrErr->size() > 1)
66-
return make_error<InstrProfError>(
67-
instrprof_error::unable_to_correlate_profile,
68-
"using multiple objects is not yet supported");
69-
DebugInfoFilename = *DsymObjectsOrErr->begin();
62+
InstrProfCorrelator::get(StringRef Filename, ProfCorrelatorKind FileKind) {
63+
if (FileKind == DEBUG_INFO) {
64+
auto DsymObjectsOrErr =
65+
object::MachOObjectFile::findDsymObjectMembers(Filename);
66+
if (auto Err = DsymObjectsOrErr.takeError())
67+
return std::move(Err);
68+
if (!DsymObjectsOrErr->empty()) {
69+
// TODO: Enable profile correlation when there are multiple objects in a
70+
// dSYM bundle.
71+
if (DsymObjectsOrErr->size() > 1)
72+
return make_error<InstrProfError>(
73+
instrprof_error::unable_to_correlate_profile,
74+
"using multiple objects is not yet supported");
75+
Filename = *DsymObjectsOrErr->begin();
76+
}
7077
}
71-
auto BufferOrErr =
72-
errorOrToExpected(MemoryBuffer::getFile(DebugInfoFilename));
78+
auto BufferOrErr = errorOrToExpected(MemoryBuffer::getFile(Filename));
7379
if (auto Err = BufferOrErr.takeError())
7480
return std::move(Err);
7581

76-
return get(std::move(*BufferOrErr));
82+
return get(std::move(*BufferOrErr), FileKind);
7783
}
7884

7985
llvm::Expected<std::unique_ptr<InstrProfCorrelator>>
80-
InstrProfCorrelator::get(std::unique_ptr<MemoryBuffer> Buffer) {
86+
InstrProfCorrelator::get(std::unique_ptr<MemoryBuffer> Buffer,
87+
ProfCorrelatorKind FileKind) {
8188
auto BinOrErr = object::createBinary(*Buffer);
8289
if (auto Err = BinOrErr.takeError())
8390
return std::move(Err);
@@ -88,9 +95,11 @@ InstrProfCorrelator::get(std::unique_ptr<MemoryBuffer> Buffer) {
8895
return std::move(Err);
8996
auto T = Obj->makeTriple();
9097
if (T.isArch64Bit())
91-
return InstrProfCorrelatorImpl<uint64_t>::get(std::move(*CtxOrErr), *Obj);
98+
return InstrProfCorrelatorImpl<uint64_t>::get(std::move(*CtxOrErr), *Obj,
99+
FileKind);
92100
if (T.isArch32Bit())
93-
return InstrProfCorrelatorImpl<uint32_t>::get(std::move(*CtxOrErr), *Obj);
101+
return InstrProfCorrelatorImpl<uint32_t>::get(std::move(*CtxOrErr), *Obj,
102+
FileKind);
94103
}
95104
return make_error<InstrProfError>(
96105
instrprof_error::unable_to_correlate_profile, "not an object file");
@@ -132,29 +141,33 @@ template <class IntPtrT>
132141
llvm::Expected<std::unique_ptr<InstrProfCorrelatorImpl<IntPtrT>>>
133142
InstrProfCorrelatorImpl<IntPtrT>::get(
134143
std::unique_ptr<InstrProfCorrelator::Context> Ctx,
135-
const object::ObjectFile &Obj) {
136-
if (Obj.isELF() || Obj.isMachO()) {
137-
auto DICtx = DWARFContext::create(Obj);
138-
return std::make_unique<DwarfInstrProfCorrelator<IntPtrT>>(std::move(DICtx),
139-
std::move(Ctx));
144+
const object::ObjectFile &Obj, ProfCorrelatorKind FileKind) {
145+
if (FileKind == DEBUG_INFO) {
146+
if (Obj.isELF() || Obj.isMachO()) {
147+
auto DICtx = DWARFContext::create(Obj);
148+
return std::make_unique<DwarfInstrProfCorrelator<IntPtrT>>(
149+
std::move(DICtx), std::move(Ctx));
150+
}
151+
return make_error<InstrProfError>(
152+
instrprof_error::unable_to_correlate_profile,
153+
"unsupported debug info format (only DWARF is supported)");
140154
}
141155
return make_error<InstrProfError>(
142156
instrprof_error::unable_to_correlate_profile,
143-
"unsupported debug info format (only DWARF is supported)");
157+
"unsupported correlation file type (only DWARF is supported)");
144158
}
145159

146160
template <class IntPtrT>
147161
Error InstrProfCorrelatorImpl<IntPtrT>::correlateProfileData(int MaxWarnings) {
148162
assert(Data.empty() && Names.empty() && NamesVec.empty());
149163
correlateProfileDataImpl(MaxWarnings);
150-
if (Data.empty() || NamesVec.empty())
164+
if (this->Data.empty())
151165
return make_error<InstrProfError>(
152166
instrprof_error::unable_to_correlate_profile,
153-
"could not find any profile metadata in debug info");
154-
auto Result =
155-
collectGlobalObjectNameStrings(NamesVec, /*doCompression=*/false, Names);
156-
CounterOffsets.clear();
157-
NamesVec.clear();
167+
"could not find any profile data metadata in correlated file");
168+
Error Result = correlateProfileNameImpl();
169+
this->CounterOffsets.clear();
170+
this->NamesVec.clear();
158171
return Result;
159172
}
160173

@@ -189,7 +202,7 @@ Error InstrProfCorrelatorImpl<IntPtrT>::dumpYaml(int MaxWarnings,
189202
if (Data.Probes.empty())
190203
return make_error<InstrProfError>(
191204
instrprof_error::unable_to_correlate_profile,
192-
"could not find any profile metadata in debug info");
205+
"could not find any profile data metadata in debug info");
193206
yaml::Output YamlOS(OS);
194207
YamlOS << Data;
195208
return Error::success();
@@ -365,3 +378,16 @@ void DwarfInstrProfCorrelator<IntPtrT>::correlateProfileDataImpl(
365378
WithColor::warning() << format("Suppressed %d additional warnings\n",
366379
NumSuppressedWarnings);
367380
}
381+
382+
template <class IntPtrT>
383+
Error DwarfInstrProfCorrelator<IntPtrT>::correlateProfileNameImpl() {
384+
if (this->NamesVec.empty()) {
385+
return make_error<InstrProfError>(
386+
instrprof_error::unable_to_correlate_profile,
387+
"could not find any profile name metadata in debug info");
388+
}
389+
auto Result =
390+
collectGlobalObjectNameStrings(this->NamesVec,
391+
/*doCompression=*/false, this->Names);
392+
return Result;
393+
}

llvm/lib/ProfileData/InstrProfReader.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -566,9 +566,9 @@ Error RawInstrProfReader<IntPtrT>::readHeader(
566566
"\nPLEASE update this tool to version in the raw profile, or "
567567
"regenerate raw profile with expected version.")
568568
.str());
569-
if (useDebugInfoCorrelate() && !Correlator)
569+
if (useCorrelate() && !Correlator)
570570
return error(instrprof_error::missing_debug_info_for_correlation);
571-
if (!useDebugInfoCorrelate() && Correlator)
571+
if (!useCorrelate() && Correlator)
572572
return error(instrprof_error::unexpected_debug_info_for_correlation);
573573

574574
BinaryIdsSize = swap(Header.BinaryIdsSize);

0 commit comments

Comments
 (0)