Index: llvm/trunk/lib/ProfileData/SampleProfReader.cpp =================================================================== --- llvm/trunk/lib/ProfileData/SampleProfReader.cpp +++ llvm/trunk/lib/ProfileData/SampleProfReader.cpp @@ -127,19 +127,52 @@ 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:1000 string_view >:437 + // ":1000" and ":437" are used as anchor points so the string above will + // be interpreted as + // target: _M_construct + // count: 1000 + // target: string_view > + // 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; Index: llvm/trunk/unittests/ProfileData/SampleProfTest.cpp =================================================================== --- llvm/trunk/unittests/ProfileData/SampleProfTest.cpp +++ llvm/trunk/unittests/ProfileData/SampleProfTest.cpp @@ -77,6 +77,9 @@ BarSamples.addTotalSamples(20301); BarSamples.addHeadSamples(1437); BarSamples.addBodySamples(1, 0, 1437); + BarSamples.addCalledTargetSamples(1, 0, "_M_construct", 1000); + BarSamples.addCalledTargetSamples( + 1, 0, "string_view >", 437); StringMap Profiles; Profiles[FooName] = std::move(FooSamples); @@ -104,6 +107,11 @@ FunctionSamples &ReadBarSamples = ReadProfiles[BarName]; ASSERT_EQ(20301u, ReadBarSamples.getTotalSamples()); ASSERT_EQ(1437u, ReadBarSamples.getHeadSamples()); + ErrorOr CTMap = + ReadBarSamples.findCallTargetMapAt(1, 0); + ASSERT_FALSE(CTMap.getError()); + ASSERT_EQ(1000u, CTMap.get()["_M_construct"]); + ASSERT_EQ(437u, CTMap.get()["string_view >"]); auto VerifySummary = [](ProfileSummary &Summary) mutable { ASSERT_EQ(ProfileSummary::PSK_Sample, Summary.getKind());