llvm.org GIT mirror llvm / f53ccf3
[SampleFDO] Extend SampleProfReader to handle demangled names. 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 Wei Mi 1 year, 7 months ago
2 changed file(s) with 50 addition(s) and 9 deletion(s). Raw diff Collapse all Expand all
126126 if (Rest.substr(0, n3).getAsInteger(10, NumSamples))
127127 return false;
128128 }
129 // Find call targets and their sample counts.
130 // Note: In some cases, there are symbols in the profile which are not
131 // mangled. To accommodate such cases, use colon + integer pairs as the
132 // anchor points.
133 // An example:
134 // _M_construct:1000 string_view >:437
135 // ":1000" and ":437" are used as anchor points so the string above will
136 // be interpreted as
137 // target: _M_construct
138 // count: 1000
139 // target: string_view >
140 // count: 437
129141 while (n3 != StringRef::npos) {
130142 n3 += Rest.substr(n3).find_first_not_of(' ');
131143 Rest = Rest.substr(n3);
132 n3 = Rest.find(' ');
133 StringRef pair = Rest;
134 if (n3 != StringRef::npos) {
135 pair = Rest.substr(0, n3);
144 n3 = Rest.find_first_of(':');
145 if (n3 == StringRef::npos || n3 == 0)
146 return false;
147
148 StringRef Target;
149 uint64_t count, n4;
150 while (true) {
151 // Get the segment after the current colon.
152 StringRef AfterColon = Rest.substr(n3 + 1);
153 // Get the target symbol before the current colon.
154 Target = Rest.substr(0, n3);
155 // Check if the word after the current colon is an integer.
156 n4 = AfterColon.find_first_of(' ');
157 n4 = (n4 != StringRef::npos) ? n3 + n4 + 1 : Rest.size();
158 StringRef WordAfterColon = Rest.substr(n3 + 1, n4 - n3 - 1);
159 if (!WordAfterColon.getAsInteger(10, count))
160 break;
161
162 // Try to find the next colon.
163 uint64_t n5 = AfterColon.find_first_of(':');
164 if (n5 == StringRef::npos)
165 return false;
166 n3 += n5 + 1;
136167 }
137 size_t n4 = pair.find(':');
138 uint64_t count;
139 if (pair.substr(n4 + 1).getAsInteger(10, count))
140 return false;
141 TargetCountMap[pair.substr(0, n4)] = count;
168
169 // An anchor point is found. Save the {target, count} pair
170 TargetCountMap[Target] = count;
171 if (n4 == Rest.size())
172 break;
173 // Change n3 to the next blank space after colon + integer pair.
174 n3 = n4;
142175 }
143176 } else {
144177 IsCallsite = true;
7676 BarSamples.addTotalSamples(20301);
7777 BarSamples.addHeadSamples(1437);
7878 BarSamples.addBodySamples(1, 0, 1437);
79 BarSamples.addCalledTargetSamples(1, 0, "_M_construct", 1000);
80 BarSamples.addCalledTargetSamples(
81 1, 0, "string_view >", 437);
7982
8083 StringMap Profiles;
8184 Profiles[FooName] = std::move(FooSamples);
103106 FunctionSamples &ReadBarSamples = ReadProfiles[BarName];
104107 ASSERT_EQ(20301u, ReadBarSamples.getTotalSamples());
105108 ASSERT_EQ(1437u, ReadBarSamples.getHeadSamples());
109 ErrorOr CTMap =
110 ReadBarSamples.findCallTargetMapAt(1, 0);
111 ASSERT_FALSE(CTMap.getError());
112 ASSERT_EQ(1000u, CTMap.get()["_M_construct"]);
113 ASSERT_EQ(437u, CTMap.get()["string_view >"]);
106114
107115 auto VerifySummary = [](ProfileSummary &Summary) mutable {
108116 ASSERT_EQ(ProfileSummary::PSK_Sample, Summary.getKind());