Skip to content

Commit

Permalink
[SampleFDO] Extend SampleProfReader to handle demangled names.
Browse files Browse the repository at this point in the history
SampleProfReader assumes function names in the profile are all mangled names.
However, there are cases that few demangled names are somehow contained in
the profile (usually because of debug info problems), which may trigger parsing
error in SampleProfReader and cause the whole profile to be unusable. The patch
extends SampleProfReader to handle profiles with demangled names, so that those
profiles can still be useful.

Differential revision: https://reviews.llvm.org/D44161


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@326905 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
wmi-11 committed Mar 7, 2018
1 parent a446275 commit f53ccf3
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 9 deletions.
51 changes: 42 additions & 9 deletions lib/ProfileData/SampleProfReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,19 +127,52 @@ static bool ParseLine(const StringRef &Input, bool &IsCallsite, uint32_t &Depth,
if (Rest.substr(0, n3).getAsInteger(10, NumSamples))
return false;
}
// Find call targets and their sample counts.
// Note: In some cases, there are symbols in the profile which are not
// mangled. To accommodate such cases, use colon + integer pairs as the
// anchor points.
// An example:
// _M_construct<char *>:1000 string_view<std::allocator<char> >:437
// ":1000" and ":437" are used as anchor points so the string above will
// be interpreted as
// target: _M_construct<char *>
// count: 1000
// target: string_view<std::allocator<char> >
// count: 437
while (n3 != StringRef::npos) {
n3 += Rest.substr(n3).find_first_not_of(' ');
Rest = Rest.substr(n3);
n3 = Rest.find(' ');
StringRef pair = Rest;
if (n3 != StringRef::npos) {
pair = Rest.substr(0, n3);
}
size_t n4 = pair.find(':');
uint64_t count;
if (pair.substr(n4 + 1).getAsInteger(10, count))
n3 = Rest.find_first_of(':');
if (n3 == StringRef::npos || n3 == 0)
return false;
TargetCountMap[pair.substr(0, n4)] = count;

StringRef Target;
uint64_t count, n4;
while (true) {
// Get the segment after the current colon.
StringRef AfterColon = Rest.substr(n3 + 1);
// Get the target symbol before the current colon.
Target = Rest.substr(0, n3);
// Check if the word after the current colon is an integer.
n4 = AfterColon.find_first_of(' ');
n4 = (n4 != StringRef::npos) ? n3 + n4 + 1 : Rest.size();
StringRef WordAfterColon = Rest.substr(n3 + 1, n4 - n3 - 1);
if (!WordAfterColon.getAsInteger(10, count))
break;

// Try to find the next colon.
uint64_t n5 = AfterColon.find_first_of(':');
if (n5 == StringRef::npos)
return false;
n3 += n5 + 1;
}

// An anchor point is found. Save the {target, count} pair
TargetCountMap[Target] = count;
if (n4 == Rest.size())
break;
// Change n3 to the next blank space after colon + integer pair.
n3 = n4;
}
} else {
IsCallsite = true;
Expand Down
8 changes: 8 additions & 0 deletions unittests/ProfileData/SampleProfTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ struct SampleProfTest : ::testing::Test {
BarSamples.addTotalSamples(20301);
BarSamples.addHeadSamples(1437);
BarSamples.addBodySamples(1, 0, 1437);
BarSamples.addCalledTargetSamples(1, 0, "_M_construct<char *>", 1000);
BarSamples.addCalledTargetSamples(
1, 0, "string_view<std::allocator<char> >", 437);

StringMap<FunctionSamples> Profiles;
Profiles[FooName] = std::move(FooSamples);
Expand Down Expand Up @@ -104,6 +107,11 @@ struct SampleProfTest : ::testing::Test {
FunctionSamples &ReadBarSamples = ReadProfiles[BarName];
ASSERT_EQ(20301u, ReadBarSamples.getTotalSamples());
ASSERT_EQ(1437u, ReadBarSamples.getHeadSamples());
ErrorOr<SampleRecord::CallTargetMap> CTMap =
ReadBarSamples.findCallTargetMapAt(1, 0);
ASSERT_FALSE(CTMap.getError());
ASSERT_EQ(1000u, CTMap.get()["_M_construct<char *>"]);
ASSERT_EQ(437u, CTMap.get()["string_view<std::allocator<char> >"]);

auto VerifySummary = [](ProfileSummary &Summary) mutable {
ASSERT_EQ(ProfileSummary::PSK_Sample, Summary.getKind());
Expand Down

0 comments on commit f53ccf3

Please sign in to comment.