Skip to content

Commit 870d957

Browse files
resolve comments
1 parent 1012575 commit 870d957

File tree

10 files changed

+85
-47
lines changed

10 files changed

+85
-47
lines changed

llvm/include/llvm/ProfileData/SampleProf.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1027,6 +1027,20 @@ class FunctionSamples {
10271027
return VirtualCallsiteTypeCounts[mapIRLocToProfileLoc(Loc)];
10281028
}
10291029

1030+
// At location \p Loc, add a type sample for the given \p Type with
1031+
// \p Count. This function uses saturating arithmetic to clamp the result to
1032+
// maximum uint64_t (the counter type) and returns counter_overflow to caller
1033+
// if the actual result is larger than maximum uint64_t.
1034+
sampleprof_error addTypeSamplesAt(const LineLocation &Loc, FunctionId Type,
1035+
uint64_t Count) {
1036+
auto &TypeCounts = getTypeSamplesAt(Loc);
1037+
bool Overflowed = false;
1038+
TypeCounts[Type] = SaturatingMultiplyAdd(Count, /* Weight= */ (uint64_t)1,
1039+
TypeCounts[Type], &Overflowed);
1040+
return Overflowed ? sampleprof_error::counter_overflow
1041+
: sampleprof_error::success;
1042+
}
1043+
10301044
/// Scale \p Other sample counts by \p Weight and add the scaled result to the
10311045
/// type samples for the undrifted location of \p Loc.
10321046
template <typename T>

llvm/test/tools/llvm-profgen/Inputs/dap-perf-trace.txt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
0 0x7b10 [0x88]: PERF_RECORD_MMAP2 3446532/3446532: [0x200000(0x60000) @ 0 08:01 527501 0]: r--p /path/to/dap.perfbin
2-
0 0x7b98 [0x88]: PERF_RECORD_MMAP2 3446532/3446532: [0x260000(0x153000) @ 0x5f000 08:01 527501 0]: r-xp /path/to/dap.perfbin
3-
0 0x7c20 [0x88]: PERF_RECORD_MMAP2 3446532/3446532: [0x3b3000(0xc000) @ 0x1b1000 08:01 527501 0]: r--p /path/to/dap.perfbin
4-
0 0x7ca8 [0x88]: PERF_RECORD_MMAP2 3446532/3446532: [0x3bf000(0x3000) @ 0x1bc000 08:01 527501 0]: rw-p /path/to/dap.perfbin
1+
0 0x7b10 [0x88]: PERF_RECORD_MMAP2 3446532/3446532: [0x200000(0x60000) @ 0 08:01 527501 0]: r--p /path/to/dap.bin
2+
0 0x7b98 [0x88]: PERF_RECORD_MMAP2 3446532/3446532: [0x260000(0x153000) @ 0x5f000 08:01 527501 0]: r-xp /path/to/dap.bin
3+
0 0x7c20 [0x88]: PERF_RECORD_MMAP2 3446532/3446532: [0x3b3000(0xc000) @ 0x1b1000 08:01 527501 0]: r--p /path/to/dap.bin
4+
0 0x7ca8 [0x88]: PERF_RECORD_MMAP2 3446532/3446532: [0x3bf000(0x3000) @ 0x1bc000 08:01 527501 0]: rw-p /path/to/dap.bin
55
1282514021937402 0x8660 [0x60]: PERF_RECORD_SAMPLE(IP, 0x4002): 3446532/3446532: 0x2608a2 period: 233 addr: 0x3b3f70
66
1282514022939813 0x87b0 [0x60]: PERF_RECORD_SAMPLE(IP, 0x4002): 3446532/3446532: 0x2608a2 period: 233 addr: 0x3b3fb0
77
1282514023932029 0x8a00 [0x60]: PERF_RECORD_SAMPLE(IP, 0x4002): 3446532/3446532: 0x2608a2 period: 233 addr: 0x3b3fb0

llvm/test/tools/llvm-profgen/afdo-with-vtable.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
RUN: llvm-profgen --perfscript=%p/Inputs/lbr-perf-for-dap.script --data-access-profile=%p/Inputs/dap-perf-trace.txt \
2-
RUN: --binary=%p/Inputs/dap.perfbin --format=text --pid=3446532 \
2+
RUN: --binary=%p/Inputs/dap.bin --format=text --pid=3446532 \
33
RUN: -ignore-stack-samples -use-dwarf-correlation -o %t.afdo
44

55
RUN: llvm-profdata show --sample --function=_Z9loop_funciii %t.afdo 2>&1 | FileCheck %s

llvm/tools/llvm-profgen/PerfReader.cpp

Lines changed: 24 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@
1818
#include "llvm/Support/Process.h"
1919
#include "llvm/Support/ToolOutputFile.h"
2020

21-
#include <regex>
22-
2321
#define DEBUG_TYPE "perf-reader"
2422

2523
cl::opt<bool> SkipSymbolization("skip-symbolization",
@@ -377,15 +375,24 @@ PerfReaderBase::create(ProfiledBinary *Binary, PerfInputFile &PerfInput,
377375
return PerfReader;
378376
}
379377

380-
void PerfReaderBase::parseDataAccessPerfTraces(
378+
Error PerfReaderBase::parseDataAccessPerfTraces(
381379
StringRef DataAccessPerfTraceFile, std::optional<int32_t> PIDFilter) {
382-
std::regex logRegex(
383-
R"(^.*?PERF_RECORD_SAMPLE\(.*?\):\s*(\d+)\/(\d+):\s*(0x[0-9a-fA-F]+)\s+period:\s*\d+\s+addr:\s*(0x[0-9a-fA-F]+)$)");
380+
// A perf_record_sample line is like
381+
// . 1282514022939813 0x87b0 [0x60]: PERF_RECORD_SAMPLE(IP, 0x4002):
382+
// 3446532/3446532: 0x2608a2 period: 233 addr: 0x3b3fb0
383+
constexpr static const char *const DataAccessSamplePattern =
384+
"PERF_RECORD_SAMPLE\\([A-Za-z]+, 0x[0-9a-fA-F]+\\): "
385+
"([0-9]+)\\/[0-9]+: (0x[0-9a-fA-F]+) period: [0-9]+ addr: "
386+
"(0x[0-9a-fA-F]+)";
387+
388+
llvm::Regex logRegex(DataAccessSamplePattern);
384389

385390
auto BufferOrErr = MemoryBuffer::getFile(DataAccessPerfTraceFile);
386391
std::error_code EC = BufferOrErr.getError();
387392
if (EC)
388-
exitWithError("Failed to open perf trace file: " + DataAccessPerfTraceFile);
393+
return make_error<StringError>("Failed to open perf trace file: " +
394+
DataAccessPerfTraceFile,
395+
inconvertibleErrorCode());
389396

390397
assert(!SampleCounters.empty() && "Sample counters should not be empty!");
391398
SampleCounter &Counter = SampleCounters.begin()->second;
@@ -403,33 +410,28 @@ void PerfReaderBase::parseDataAccessPerfTraces(
403410
continue;
404411
}
405412

406-
// Skip lines that do not contain "PERF_RECORD_SAMPLE".
407-
if (!Line.contains("PERF_RECORD_SAMPLE")) {
408-
continue;
409-
}
410-
411-
std::smatch matches;
412-
const std::string LineStr = Line.str();
413-
414-
if (std::regex_search(LineStr.begin(), LineStr.end(), matches, logRegex)) {
415-
if (matches.size() != 5)
416-
continue;
417-
418-
const int32_t PID = std::stoi(matches[1].str());
419-
if (PIDFilter && *PIDFilter != PID) {
413+
SmallVector<StringRef> Fields;
414+
if (logRegex.match(Line, &Fields)) {
415+
int32_t PID = 0;
416+
Fields[1].getAsInteger(0, PID);
417+
if (PIDFilter.has_value() && *PIDFilter != PID) {
420418
continue;
421419
}
422420

423-
const uint64_t DataAddress = std::stoull(matches[4].str(), nullptr, 16);
421+
uint64_t DataAddress = 0;
422+
Fields[3].getAsInteger(0, DataAddress);
423+
424424
StringRef DataSymbol = Binary->symbolizeDataAddress(
425425
Binary->CanonicalizeNonTextAddress(DataAddress));
426426
if (DataSymbol.starts_with("_ZTV")) {
427-
const uint64_t IP = std::stoull(matches[3].str(), nullptr, 16);
427+
uint64_t IP = 0;
428+
Fields[2].getAsInteger(0, IP);
428429
Counter.recordDataAccessCount(Binary->canonicalizeVirtualAddress(IP),
429430
DataSymbol, 1);
430431
}
431432
}
432433
}
434+
return Error::success();
433435
}
434436

435437
PerfInputFile

llvm/tools/llvm-profgen/PerfReader.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "ProfiledBinary.h"
1313
#include "llvm/Support/Casting.h"
1414
#include "llvm/Support/CommandLine.h"
15+
#include "llvm/Support/Error.h"
1516
#include "llvm/Support/Regex.h"
1617
#include <cstdint>
1718
#include <fstream>
@@ -396,6 +397,7 @@ using BranchSample = std::map<std::pair<uint64_t, uint64_t>, uint64_t>;
396397
// which is represented as the start and end offset pair.
397398
using RangeSample = std::map<std::pair<uint64_t, uint64_t>, uint64_t>;
398399
// <<inst-addr, vtable-data-symbol>, count> map for data access samples.
400+
// The instruction address is the virtual address in the binary.
399401
using DataAccessSample = std::map<std::pair<uint64_t, StringRef>, uint64_t>;
400402
// Wrapper for sample counters including range counter and branch counter
401403
struct SampleCounter {
@@ -581,8 +583,8 @@ class PerfReaderBase {
581583
virtual void parsePerfTraces() = 0;
582584

583585
// Parse the <ip, vtable-data-symbol> from the data access perf trace file,
584-
// and accummuate the data access count for each <ip, data-symbol> pair.
585-
void
586+
// and accumulate the data access count for each <ip, data-symbol> pair.
587+
Error
586588
parseDataAccessPerfTraces(StringRef DataAccessPerfFile,
587589
std::optional<int32_t> PIDFilter = std::nullopt);
588590

@@ -615,6 +617,8 @@ class PerfScriptReader : public PerfReaderBase {
615617

616618
// Parse a single line of a PERF_RECORD_MMAP event looking for a
617619
// mapping between the binary name and its memory layout.
620+
// TODO: Move this static method from PerScriptReader (subclass) to
621+
// PerfReaderBase (superclass).
618622
static bool extractMMapEventForBinary(ProfiledBinary *Binary, StringRef Line,
619623
MMapEvent &MMap);
620624

llvm/tools/llvm-profgen/ProfileGenerator.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ void ProfileGenerator::generateLineNumBasedProfile() {
552552
LineLocation Loc(
553553
FrameVec.back().Location.LineOffset,
554554
getBaseDiscriminator(FrameVec.back().Location.Discriminator));
555-
FunctionProfile.getTypeSamplesAt(Loc)[FunctionId(IpData.second)] += Count;
555+
FunctionProfile.addTypeSamplesAt(Loc, FunctionId(IpData.second), Count);
556556
}
557557
}
558558

llvm/tools/llvm-profgen/ProfiledBinary.cpp

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ void ProfiledBinary::setPreferredTextSegmentAddresses(const ELFFile<ELFT> &Obj,
340340
PhdrInfo Info;
341341
Info.FileOffset = Phdr.p_offset;
342342
Info.FileSz = Phdr.p_filesz;
343-
Info.vAddr = Phdr.p_vaddr;
343+
Info.VirtualAddr = Phdr.p_vaddr;
344344
NonTextPhdrInfo.push_back(Info);
345345
}
346346
}
@@ -369,7 +369,7 @@ uint64_t ProfiledBinary::CanonicalizeNonTextAddress(uint64_t Address) {
369369
if (PhdrInfo.FileOffset <= FileOffset &&
370370
FileOffset < PhdrInfo.FileOffset + PhdrInfo.FileSz) {
371371
// If it is, return the virtual address of the segment.
372-
return PhdrInfo.vAddr + (FileOffset - PhdrInfo.FileOffset);
372+
return PhdrInfo.VirtualAddr + (FileOffset - PhdrInfo.FileOffset);
373373
}
374374
}
375375

@@ -945,11 +945,10 @@ SampleContextFrameVector ProfiledBinary::symbolize(const InstructionPointer &IP,
945945
bool UseProbeDiscriminator) {
946946
assert(this == IP.Binary &&
947947
"Binary should only symbolize its own instruction");
948-
auto Addr = object::SectionedAddress{IP.Address,
949-
object::SectionedAddress::UndefSection};
950-
DIInliningInfo InlineStack = unwrapOrError(
951-
Symbolizer->symbolizeInlinedCode(SymbolizerPath.str(), Addr),
952-
SymbolizerPath);
948+
DIInliningInfo InlineStack =
949+
unwrapOrError(Symbolizer->symbolizeInlinedCode(
950+
SymbolizerPath.str(), getSectionedAddress(IP.Address)),
951+
SymbolizerPath);
953952

954953
SampleContextFrameVector CallStack;
955954
for (int32_t I = InlineStack.getNumberOfFrames() - 1; I >= 0; I--) {
@@ -979,11 +978,13 @@ SampleContextFrameVector ProfiledBinary::symbolize(const InstructionPointer &IP,
979978
}
980979

981980
StringRef ProfiledBinary::symbolizeDataAddress(uint64_t Address) {
982-
DIGlobal DataDIGlobal = unwrapOrError(
983-
Symbolizer->symbolizeData(SymbolizerPath.str(), {Address, 0}),
984-
SymbolizerPath);
985-
auto It = NameStrings.insert(DataDIGlobal.Name);
986-
return StringRef(*It.first);
981+
DIGlobal DataDIGlobal =
982+
unwrapOrError(Symbolizer->symbolizeData(SymbolizerPath.str(),
983+
getSectionedAddress(Address)),
984+
SymbolizerPath);
985+
decltype(NameStrings)::iterator Iter;
986+
std::tie(Iter, std::ignore) = NameStrings.insert(DataDIGlobal.Name);
987+
return StringRef(*Iter);
987988
}
988989

989990
void ProfiledBinary::computeInlinedContextSizeForRange(uint64_t RangeBegin,

llvm/tools/llvm-profgen/ProfiledBinary.h

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ class ProfiledBinary {
293293
struct PhdrInfo {
294294
uint64_t FileOffset;
295295
uint64_t FileSz;
296-
uint64_t vAddr;
296+
uint64_t VirtualAddr;
297297
};
298298

299299
// Program header information for non-text PT_LOAD segments.
@@ -328,6 +328,16 @@ class ProfiledBinary {
328328

329329
void setPreferredTextSegmentAddresses(const ObjectFile *O);
330330

331+
// LLVMSymbolizer's symbolize{Code, Data} interfaces requires a section index
332+
// for each address to be symbolized. This is a helper function to
333+
// construct a SectionedAddress object with the given address and section
334+
// index. The section index is set to UndefSection by default.
335+
static object::SectionedAddress getSectionedAddress(
336+
uint64_t Address,
337+
uint64_t SectionIndex = object::SectionedAddress::UndefSection) {
338+
return object::SectionedAddress{Address, SectionIndex};
339+
}
340+
331341
template <class ELFT>
332342
void setPreferredTextSegmentAddresses(const ELFFile<ELFT> &Obj,
333343
StringRef FileName);
@@ -634,8 +644,10 @@ class ProfiledBinary {
634644
MMapNonTextEvents.push_back(MMap);
635645
}
636646

637-
// Given a runtime address, canonicalize it to the virtual address in the
638-
// binary.
647+
// Given a non-text runtime address, canonicalize it to the virtual address in
648+
// the binary.
649+
// TODO: Consider unifying the canonicalization of text and non-text addresses
650+
// in the ProfiledBinary class.
639651
uint64_t CanonicalizeNonTextAddress(uint64_t Address);
640652

641653
bool getTrackFuncContextSize() { return TrackFuncContextSize; }

llvm/tools/llvm-profgen/llvm-profgen.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ static cl::opt<std::string> DebugBinPath(
6969

7070
static cl::opt<std::string> DataAccessProfileFilename(
7171
"data-access-profile", cl::value_desc("data-access-profile"),
72-
cl::desc("Path of the data access profile to be generated."),
72+
cl::desc("Path to the data access profile to be generated."),
7373
cl::cat(ProfGenCategory));
7474

7575
extern cl::opt<bool> ShowDisassemblyOnly;
@@ -188,7 +188,12 @@ int main(int argc, const char *argv[]) {
188188
// Parse the data access perf traces into <ip, data-addr> pairs, symbolize
189189
// the data-addr to data-symbol. If the data-addr is a vtable, increment
190190
// counters for the <ip, data-symbol> pair.
191-
Reader->parseDataAccessPerfTraces(DataAccessProfileFilename, PIDFilter);
191+
if (Error E = Reader->parseDataAccessPerfTraces(DataAccessProfileFilename,
192+
PIDFilter)) {
193+
handleAllErrors(std::move(E), [&](const StringError &SE) {
194+
exitWithError(SE.getMessage());
195+
});
196+
}
192197
}
193198

194199
if (SkipSymbolization)

0 commit comments

Comments
 (0)