LLVM: lib/ProfileData/SampleProfReader.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
40#include
41#include
42#include
43#include
44#include
45#include <system_error>
46#include
47
48using namespace llvm;
50
51#define DEBUG_TYPE "samplepgo-reader"
52
53
54
55
58 cl::desc("Profile uses flow sensitive discriminators"));
59
60
61
62
63
66 OS << "Function: " << FS.getContext().toString() << ": " << FS;
67}
68
69
71 std::vector V;
73 for (const auto &I : V)
75}
76
79 auto DumpBody = [&](const BodySampleMap &BodySamples) {
80 for (const auto &I : BodySamples) {
85 if (Loc.Discriminator)
86 JOS.attribute("discriminator", Loc.Discriminator);
88
90 if (!CallTargets.empty()) {
92 for (const auto &J : CallTargets) {
94 JOS.attribute("function", J.first.str());
95 JOS.attribute("samples", J.second);
96 });
97 }
98 });
99 }
100 });
101 }
102 };
103
104 auto DumpCallsiteSamples = [&](const CallsiteSampleMap &CallsiteSamples) {
105 for (const auto &I : CallsiteSamples)
106 for (const auto &FS : I.second) {
111 if (Loc.Discriminator)
112 JOS.attribute("discriminator", Loc.Discriminator);
115 });
116 }
117 };
118
122 if (TopLevel)
124
126 if (!BodySamples.empty())
127 JOS.attributeArray("body", [&] { DumpBody(BodySamples); });
128
130 if (!CallsiteSamples.empty())
132 [&] { DumpCallsiteSamples(CallsiteSamples); });
133 });
134}
135
136
138 std::vector V;
142 for (const auto &F : V)
145
146
147 OS << "\n";
148}
149
150
151
152
153
154
155
156
159 if (Input[0] == ' ')
160 return false;
161 size_t n2 = Input.rfind(':');
162 size_t n1 = Input.rfind(':', n2 - 1);
163 FName = Input.substr(0, n1);
164 if (Input.substr(n1 + 1, n2 - n1 - 1).getAsInteger(10, NumSamples))
165 return false;
166 if (Input.substr(n2 + 1).getAsInteger(10, NumHeadSamples))
167 return false;
168 return true;
169}
170
171
172static bool isOffsetLegal(unsigned L) { return (L & 0xffff) == L; }
173
174
175
176
177
178
179
180
183 if (Input.starts_with("!CFGChecksum:")) {
184 StringRef CFGInfo = Input.substr(strlen("!CFGChecksum:")).trim();
185 return !CFGInfo.getAsInteger(10, FunctionHash);
186 }
187
188 if (Input.starts_with("!Attributes:")) {
189 StringRef Attrib = Input.substr(strlen("!Attributes:")).trim();
191 }
192
193 return false;
194}
195
202
203
204
207 for (size_t Index = Input.find_first_not_of(' '); Index != StringRef::npos;) {
208 size_t ColonIndex = Input.find(':', Index);
210 return false;
211 StringRef TypeName = Input.substr(Index, ColonIndex - Index);
212
213 size_t CountStartIndex = ColonIndex + 1;
214
215 size_t NextIndex = Input.find_first_of(' ', CountStartIndex);
217 if (Input.substr(CountStartIndex, NextIndex - CountStartIndex)
218 .getAsInteger(10, Count))
219 return false;
220
222 if (!Inserted)
223 return false;
226 : Input.find_first_not_of(' ', NextIndex);
227 }
228 return true;
229}
230
231
232
233
234
235
236
237
238
239
240
241
242
249 bool &IsFlat) {
251 ;
253 return false;
254
257
258
259
261 IsFlat = true;
262 return true;
263 }
265 }
266
267 size_t n1 = Input.find(':');
269 size_t n2 = Loc.find('.');
271 if (Loc.getAsInteger(10, LineOffset) || (LineOffset))
272 return false;
273 Discriminator = 0;
274 } else {
275 if (Loc.substr(0, n2).getAsInteger(10, LineOffset))
276 return false;
277 if (Loc.substr(n2 + 1).getAsInteger(10, Discriminator))
278 return false;
279 }
280
284 size_t n3 = Rest.find(' ');
287 return false;
288 } else {
290 return false;
291 }
292
293
294
295
296
297
298
299
300
301
302
303
306 Rest = Rest.substr(n3);
309 return false;
310
313 while (true) {
314
316
318
321 StringRef WordAfterColon = Rest.substr(n3 + 1, n4 - n3 - 1);
323 break;
324
325
328 return false;
329 n3 += n5 + 1;
330 }
331
332
334 if (n4 == Rest.size())
335 break;
336
337 n3 = n4;
338 }
343 } else {
346 CalleeName = Rest.substr(0, n3);
348 return false;
349 }
350 return true;
351}
352
353
354
355
356
357
358
362
364 uint32_t TopLevelProbeProfileCount = 0;
365
366
367
369
370 std::vector<SampleContext *> FlatSamples;
371
374 for (; !LineIt.is_at_eof(); ++LineIt) {
376 if (pos == LineIt->npos || (*LineIt)[pos] == '#')
377 continue;
378
379
380
381
382
383
384
385
386
387
388
389
390 if ((*LineIt)[0] != ' ') {
391 uint64_t NumSamples, NumHeadSamples;
393 if ((*LineIt, FName, NumSamples, NumHeadSamples)) {
395 "Expected 'mangled_name:NUM:NUM', found " + *LineIt);
397 }
398 DepthMetadata = 0;
405 InlineStack.clear();
406 InlineStack.push_back(&FProfile);
407 } else {
416 bool IsFlat = false;
417
418
419 if ((*LineIt, LineTy, Depth, NumSamples, LineOffset,
420 Discriminator, FName, TargetCountMap, TypeCountMap,
421 FunctionHash, Attributes, IsFlat)) {
422 switch (LineTy) {
425 "Cannot parse metadata: " + *LineIt);
426 break;
429 "Expected 'vtables [mangled_vtable:NUM]+', found " +
430 *LineIt);
431 break;
432 default:
434 "Expected 'NUM[.NUM]: NUM[ mangled_name:NUM]*', found " +
435 *LineIt);
436 }
438 }
440
442 "Found non-metadata after metadata: " + *LineIt);
444 }
445
446
448
449 while (InlineStack.size() > Depth) {
451 }
452 switch (LineTy) {
458 InlineStack.push_back(&FSamples);
459 DepthMetadata = 0;
460 break;
461 }
462
465 Result, InlineStack.back()->addCallsiteVTableTypeProfAt(
467 break;
468 }
469
472 for (const auto &name_count : TargetCountMap) {
474 LineOffset, Discriminator,
476 name_count.second));
477 }
479 Result,
480 FProfile.addBodySamples(LineOffset, Discriminator, NumSamples));
481 break;
482 }
485 if (FunctionHash) {
488 ++TopLevelProbeProfileCount;
489 }
493 DepthMetadata = Depth;
494 if (IsFlat) {
496 FlatSamples.push_back(&FProfile.getContext());
497 else
500 "!Flat may only be used at top level function.", DS_Warning));
501 }
502 break;
503 }
504 }
505 }
506 }
507
508
509
513
515 "Cannot have both context-sensitive and regular profile");
517 assert((TopLevelProbeProfileCount == 0 ||
518 TopLevelProbeProfileCount == Profiles.size()) &&
519 "Cannot have both probe-based profiles and regular profiles");
524
527
528 return Result;
529}
530
532 bool result = false;
533
534
537 if ((*LineIt)[0] != ' ') {
538 uint64_t NumSamples, NumHeadSamples;
540 result = ParseHead(*LineIt, FName, NumSamples, NumHeadSamples);
541 }
542 }
543
544 return result;
545}
546
548 unsigned NumBytesRead = 0;
550
551 if (Val > std::numeric_limits::max()) {
554 return EC;
555 } else if (Data + NumBytesRead > End) {
558 return EC;
559 }
560
561 Data += NumBytesRead;
562 return static_cast<T>(Val);
563}
564
566 StringRef Str(reinterpret_cast<const char *>(Data));
567 if (Data + Str.size() + 1 > End) {
570 return EC;
571 }
572
573 Data += Str.size() + 1;
574 return Str;
575}
576
577template
579 if (Data + sizeof(T) > End) {
582 return EC;
583 }
584
587 return Val;
588}
589
590template
593 if (std::error_code EC = Idx.getError())
594 return EC;
595 if (*Idx >= Table.size())
597 return *Idx;
598}
599
603 if (std::error_code EC = Idx.getError())
604 return EC;
605 if (RetIdx)
606 *RetIdx = *Idx;
608}
609
613 if (std::error_code EC = ContextIdx.getError())
614 return EC;
617 if (RetIdx)
618 *RetIdx = *ContextIdx;
620}
621
625 size_t Idx;
628 if (std::error_code EC = FContext.getError())
629 return EC;
631 } else {
633 if (std::error_code EC = FName.getError())
634 return EC;
636 }
637
638
640
641
642
643 if (Hash == 0) {
645 Hash = Context.getHashCode();
647 }
648 return std::make_pair(Context, Hash);
649}
650
651std::error_code
654 if (std::error_code EC = NumVTableTypes.getError())
655 return EC;
656
657 for (uint32_t I = 0; I < *NumVTableTypes; ++I) {
659 if (std::error_code EC = VTableType.getError())
660 return EC;
661
663 if (std::error_code EC = VTableSamples.getError())
664 return EC;
665
666
667
668 if (.insert(std::make_pair(*VTableType, *VTableSamples)).second) {
670 Buffer->getBufferIdentifier(), 0,
671 "Duplicate vtable type " + VTableType->str() +
672 " at the same location. Additional counters will be ignored.",
674 continue;
675 }
676 }
678}
679
680std::error_code
683 "Cannot read vtable profiles if ReadVTableProf is false");
684
685
687 if (std::error_code EC = NumCallsites.getError())
688 return EC;
689
690 for (uint32_t I = 0; I < *NumCallsites; ++I) {
692 if (std::error_code EC = LineOffset.getError())
693 return EC;
694
697
699 if (std::error_code EC = Discriminator.getError())
700 return EC;
701
702
704
706 LineLocation(*LineOffset, DiscriminatorVal))))
707 return EC;
708 }
710}
711
712std::error_code
715 if (std::error_code EC = NumSamples.getError())
716 return EC;
718
719
721 if (std::error_code EC = NumRecords.getError())
722 return EC;
723
724 for (uint32_t I = 0; I < *NumRecords; ++I) {
726 if (std::error_code EC = LineOffset.getError())
727 return EC;
728
731 }
732
734 if (std::error_code EC = Discriminator.getError())
735 return EC;
736
738 if (std::error_code EC = NumSamples.getError())
739 return EC;
740
742 if (std::error_code EC = NumCalls.getError())
743 return EC;
744
745
747
748 for (uint32_t J = 0; J < *NumCalls; ++J) {
750 if (std::error_code EC = CalledFunction.getError())
751 return EC;
752
754 if (std::error_code EC = CalledFunctionSamples.getError())
755 return EC;
756
758 *CalledFunction, *CalledFunctionSamples);
759 }
760
761 FProfile.addBodySamples(*LineOffset, DiscriminatorVal, *NumSamples);
762 }
763
764
766 if (std::error_code EC = NumCallsites.getError())
767 return EC;
768
769 for (uint32_t J = 0; J < *NumCallsites; ++J) {
771 if (std::error_code EC = LineOffset.getError())
772 return EC;
773
775 if (std::error_code EC = Discriminator.getError())
776 return EC;
777
779 if (std::error_code EC = FName.getError())
780 return EC;
781
782
784
786 LineLocation(*LineOffset, DiscriminatorVal))[*FName];
788 if (std::error_code EC = readProfile(CalleeProfile))
789 return EC;
790 }
791
794
796}
797
798std::error_code
801 Data = Start;
803 if (std::error_code EC = NumHeadSamples.getError())
804 return EC;
805
807 if (std::error_code EC = FContextHash.getError())
808 return EC;
809
810 auto &[FContext, Hash] = *FContextHash;
811
816
817 if (FContext.hasContext())
819
820 if (std::error_code EC = readProfile(FProfile))
821 return EC;
823}
824
825std::error_code
829
835 return EC;
836 }
837
839}
840
843 Data = Start;
845 switch (Entry.Type) {
848 return EC;
850 Summary->setPartialProfile(true);
859 break;
861 bool FixedLengthMD5 =
864
865
869 if (std::error_code EC = readNameTableSec(UseMD5, FixedLengthMD5))
870 return EC;
871 break;
872 }
875 return EC;
876 break;
877 }
881 return EC;
882 break;
884
885
886 if () {
888 } else {
891 "func offset table should always be sorted in CS profile");
893 return EC;
894 }
895 break;
903 return EC;
904 break;
905 }
908 return EC;
909 break;
910 default:
912 return EC;
913 break;
914 }
916}
917
919
920
921
922
923
925 return true;
926
927
928
930 return false;
931
932
933
934
936 return true;
937
938
939
940
941
942
943 return false;
944}
945
946std::error_code
951
955 return EC;
961 ProfilesToReadMetadata.insert(&I->second);
962 }
963
964 if (std::error_code EC =
966 return EC;
968}
969
971 if ()
972 return false;
976 return true;
977}
978
980
981
984
986 if (std::error_code EC = Size.getError())
987 return EC;
988
990 if (UseFuncOffsetList)
992 else
994
997 if (std::error_code EC = FContextHash.getError())
998 return EC;
999
1000 auto &[FContext, Hash] = *FContextHash;
1002 if (std::error_code EC = Offset.getError())
1003 return EC;
1004
1005 if (UseFuncOffsetList)
1007 else
1008
1009
1011 }
1012
1014}
1015
1019
1023 }
1024 }
1025
1032 }
1033
1034
1035
1036
1037
1038
1039
1040
1043 const auto &FContext = NameOffset.first;
1044 FunctionId FName = FContext.getFunction();
1047 FNameString = FName.stringRef();
1048
1049
1050
1051
1055 if (!CommonContext || !CommonContext->isPrefixOf(FContext))
1056 CommonContext = &FContext;
1057 }
1058
1059 if (CommonContext == &FContext ||
1060 (CommonContext && CommonContext->isPrefixOf(FContext))) {
1061
1062
1063 const uint8_t *FuncProfileAddr = Start + NameOffset.second;
1064 if (std::error_code EC = readFuncProfile(FuncProfileAddr))
1065 return EC;
1066 }
1067 }
1068 } else if (useMD5()) {
1071 auto GUID = MD5Hash(Name);
1074 continue;
1075 const uint8_t *FuncProfileAddr = Start + iter->second;
1077 return EC;
1078 }
1084 StringRef FuncNameStr = FuncName.stringRef();
1085 if (.count(FuncNameStr) &&
->exist(FuncNameStr))
1086 continue;
1087 const uint8_t *FuncProfileAddr = Start + NameOffset.second;
1089 return EC;
1090 }
1091 } else {
1094
1097 continue;
1098 const uint8_t *FuncProfileAddr = Start + iter->second;
1100 return EC;
1101 }
1102 }
1103
1105}
1106
1108
1109
1110
1111
1112
1113
1115
1116
1117
1118 if (!LoadFuncsToBeUsed) {
1121 return EC;
1122 }
1123 assert(Data == End && "More data is read than expected");
1124 } else {
1125
1127 return EC;
1129 }
1131 "Cannot have both context-sensitive and regular profile");
1133 "Section flag should be consistent with actual profile");
1135}
1136
1139 ProfSymList = std::make_unique();
1140
1142 return EC;
1143
1146}
1147
1148std::error_code SampleProfileReaderExtBinaryBase::decompressSection(
1150 const uint8_t *&DecompressBuf, uint64_t &DecompressBufSize) {
1151 Data = SecStart;
1152 End = SecStart + SecSize;
1154 if (std::error_code EC = DecompressSize.getError())
1155 return EC;
1156 DecompressBufSize = *DecompressSize;
1157
1159 if (std::error_code EC = CompressSize.getError())
1160 return EC;
1161
1164
1166 size_t UCSize = DecompressBufSize;
1169 if (E)
1171 DecompressBuf = reinterpret_cast<const uint8_t *>(Buffer);
1173}
1174
1176 const uint8_t *BufStart =
1177 reinterpret_cast<const uint8_t *>(Buffer->getBufferStart());
1178
1180
1181 if (!Entry.Size)
1182 continue;
1183
1184
1186 continue;
1187
1188 const uint8_t *SecStart = BufStart + Entry.Offset;
1189 uint64_t SecSize = Entry.Size;
1190
1191
1192
1193
1194
1196 if (isCompressed) {
1197 const uint8_t *DecompressBuf;
1199 if (std::error_code EC = decompressSection(
1200 SecStart, SecSize, DecompressBuf, DecompressBufSize))
1201 return EC;
1202 SecStart = DecompressBuf;
1203 SecSize = DecompressBufSize;
1204 }
1205
1206 if (std::error_code EC = readOneSection(SecStart, SecSize, Entry))
1207 return EC;
1208 if (Data != SecStart + SecSize)
1210
1211
1212 if (isCompressed) {
1213 Data = BufStart + Entry.Offset;
1214 End = BufStart + Buffer->getBufferSize();
1215 }
1216 }
1217
1219}
1220
1221std::error_code SampleProfileReaderRawBinary::verifySPMagic(uint64_t Magic) {
1225}
1226
1227std::error_code SampleProfileReaderExtBinary::verifySPMagic(uint64_t Magic) {
1231}
1232
1235 if (std::error_code EC = Size.getError())
1236 return EC;
1237
1238
1239
1240
1241
1242 bool UseMD5 = useMD5();
1243
1248 if (UseMD5)
1250 else
1251
1252
1253
1255 }
1256 for (size_t I = 0; I < *Size; ++I) {
1258 if (std::error_code EC = Name.getError())
1259 return EC;
1260 if (UseMD5) {
1265 } else
1267 }
1271}
1272
1273std::error_code
1275 bool FixedLengthMD5) {
1276 if (FixedLengthMD5) {
1277 if (!IsMD5)
1278 errs() << "If FixedLengthMD5 is true, UseMD5 has to be true";
1280 if (std::error_code EC = Size.getError())
1281 return EC;
1282
1284 "Fixed length MD5 name table does not contain specified number of "
1285 "entries");
1288
1291 for (size_t I = 0; I < *Size; ++I) {
1292 using namespace support;
1296 }
1301 }
1302
1303 if (IsMD5) {
1304 assert(!FixedLengthMD5 && "FixedLengthMD5 should be unreachable here");
1306 if (std::error_code EC = Size.getError())
1307 return EC;
1308
1313 for (size_t I = 0; I < *Size; ++I) {
1315 if (std::error_code EC = FID.getError())
1316 return EC;
1320 }
1324 }
1325
1327}
1328
1329
1330
1331
1332
1335 if (std::error_code EC = Size.getError())
1336 return EC;
1337
1341
1342
1343
1347 }
1348 for (size_t I = 0; I < *Size; ++I) {
1351 if (std::error_code EC = ContextSize.getError())
1352 return EC;
1353 for (uint32_t J = 0; J < *ContextSize; ++J) {
1355 if (std::error_code EC = FName.getError())
1356 return EC;
1358 if (std::error_code EC = LineOffset.getError())
1359 return EC;
1360
1363
1365 if (std::error_code EC = Discriminator.getError())
1366 return EC;
1367
1369 FName.get(), LineLocation(LineOffset.get(), Discriminator.get()));
1370 }
1371 }
1372
1374}
1375
1376std::error_code
1382 if (std::error_code EC = Checksum.getError())
1383 return EC;
1384 if (FProfile)
1386 }
1387
1390 if (std::error_code EC = Attributes.getError())
1391 return EC;
1392 if (FProfile)
1394 }
1395
1397
1399 if (std::error_code EC = NumCallsites.getError())
1400 return EC;
1401
1402 for (uint32_t J = 0; J < *NumCallsites; ++J) {
1404 if (std::error_code EC = LineOffset.getError())
1405 return EC;
1406
1408 if (std::error_code EC = Discriminator.getError())
1409 return EC;
1410
1412 if (std::error_code EC = FContextHash.getError())
1413 return EC;
1414
1415 auto &[FContext, Hash] = *FContextHash;
1417 if (FProfile) {
1420 *LineOffset,
1421 *Discriminator))[FContext.getFunction()]);
1422 }
1423 if (std::error_code EC =
1425 return EC;
1426 }
1427 }
1428 }
1429
1431}
1432
1437
1438 for (auto *FProfile : Profiles) {
1439 auto R = FuncMetadataIndex.find(FProfile->getContext().getHashCode());
1441 continue;
1442
1443 Data = R->second.first;
1444 End = R->second.second;
1446 return EC;
1447 assert(Data == End && "More data is read than expected");
1448 }
1450}
1451
1452std::error_code
1456 if (std::error_code EC = FContextHash.getError())
1457 return EC;
1458 auto &[FContext, Hash] = *FContextHash;
1460 auto It = Profiles.find(FContext);
1462 FProfile = &It->second;
1463
1466 return EC;
1467
1469 }
1470
1471 assert(Data == End && "More data is read than expected");
1473}
1474
1475std::error_code
1479 if (std::error_code EC = Type.getError())
1480 return EC;
1481 Entry.Type = static_cast<SecType>(*Type);
1482
1484 if (std::error_code EC = Flags.getError())
1485 return EC;
1486 Entry.Flags = *Flags;
1487
1489 if (std::error_code EC = Offset.getError())
1490 return EC;
1491 Entry.Offset = *Offset;
1492
1494 if (std::error_code EC = Size.getError())
1495 return EC;
1496 Entry.Size = *Size;
1497
1498 Entry.LayoutIndex = Idx;
1499 SecHdrTable.push_back(std::move(Entry));
1501}
1502
1505 if (std::error_code EC = EntryNum.getError())
1506 return EC;
1507
1508 for (uint64_t i = 0; i < (*EntryNum); i++)
1510 return EC;
1511
1513}
1514
1516 const uint8_t *BufStart =
1517 reinterpret_cast<const uint8_t *>(Buffer->getBufferStart());
1518 Data = BufStart;
1519 End = BufStart + Buffer->getBufferSize();
1520
1522 return EC;
1523
1525 return EC;
1526
1528}
1529
1533 if (Entry.Type == Type)
1534 Size += Entry.Size;
1535 }
1536 return Size;
1537}
1538
1540
1541
1542
1543
1544
1547 FileSize = std::max(Entry.Offset + Entry.Size, FileSize);
1548 }
1549 return FileSize;
1550}
1551
1553 std::string Flags;
1555 Flags.append("{compressed,");
1556 else
1557 Flags.append("{");
1558
1560 Flags.append("flat,");
1561
1562 switch (Entry.Type) {
1565 Flags.append("fixlenmd5,");
1567 Flags.append("md5,");
1569 Flags.append("uniq,");
1570 break;
1573 Flags.append("partial,");
1575 Flags.append("context,");
1577 Flags.append("preInlined,");
1579 Flags.append("fs-discriminator,");
1580 break;
1583 Flags.append("ordered,");
1584 break;
1587 Flags.append("probe,");
1589 Flags.append("attr,");
1590 break;
1591 default:
1592 break;
1593 }
1594 char &last = Flags.back();
1595 if (last == ',')
1596 last = '}';
1597 else
1598 Flags.append("}");
1599 return Flags;
1600}
1601
1605 OS << getSecName(Entry.Type) << " - Offset: " << Entry.Offset
1606 << ", Size: " << Entry.Size << ", Flags: " << getSecFlagsStr(Entry)
1607 << "\n";
1608 ;
1609 TotalSecsSize += Entry.Size;
1610 }
1613 "Size of 'header + sections' doesn't match the total size of profile");
1614
1615 OS << "Header Size: " << HeaderSize << "\n";
1616 OS << "Total Sections Size: " << TotalSecsSize << "\n";
1617 OS << "File Size: " << getFileSize() << "\n";
1618 return true;
1619}
1620
1622
1624 if (std::error_code EC = Magic.getError())
1625 return EC;
1626 else if (std::error_code EC = verifySPMagic(*Magic))
1627 return EC;
1628
1629
1631 if (std::error_code EC = Version.getError())
1632 return EC;
1635
1637}
1638
1640 Data = reinterpret_cast<const uint8_t *>(Buffer->getBufferStart());
1642
1644 return EC;
1645
1647 return EC;
1648
1650 return EC;
1652}
1653
1654std::error_code SampleProfileReaderBinary::readSummaryEntry(
1655 std::vector &Entries) {
1657 if (std::error_code EC = Cutoff.getError())
1658 return EC;
1659
1661 if (std::error_code EC = MinBlockCount.getError())
1662 return EC;
1663
1665 if (std::error_code EC = NumBlocks.getError())
1666 return EC;
1667
1668 Entries.emplace_back(*Cutoff, *MinBlockCount, *NumBlocks);
1670}
1671
1674 if (std::error_code EC = TotalCount.getError())
1675 return EC;
1676
1678 if (std::error_code EC = MaxBlockCount.getError())
1679 return EC;
1680
1682 if (std::error_code EC = MaxFunctionCount.getError())
1683 return EC;
1684
1686 if (std::error_code EC = NumBlocks.getError())
1687 return EC;
1688
1690 if (std::error_code EC = NumFunctions.getError())
1691 return EC;
1692
1694 if (std::error_code EC = NumSummaryEntries.getError())
1695 return EC;
1696
1697 std::vector Entries;
1698 for (unsigned i = 0; i < *NumSummaryEntries; i++) {
1699 std::error_code EC = readSummaryEntry(Entries);
1701 return EC;
1702 }
1703 Summary = std::make_unique(
1705 *MaxFunctionCount, *NumBlocks, *NumFunctions);
1706
1708}
1709
1712 reinterpret_cast<const uint8_t *>(Buffer.getBufferStart());
1714 return Magic == SPMagic();
1715}
1716
1719 reinterpret_cast<const uint8_t *>(Buffer.getBufferStart());
1722}
1723
1730
1732 if (sizeof(T) <= sizeof(uint32_t)) {
1734 if (GcovBuffer.readInt(Val) && Val <= std::numeric_limits::max())
1735 return static_cast<T>(Val);
1736 } else if (sizeof(T) <= sizeof(uint64_t)) {
1738 if (GcovBuffer.readInt64(Val) && Val <= std::numeric_limits::max())
1739 return static_cast<T>(Val);
1740 }
1741
1744 return EC;
1745}
1746
1753
1755
1758
1759
1760
1762 if (.readGCOVVersion(version))
1764
1767
1768
1770 return EC;
1771
1773}
1774
1779
1782
1784 return EC;
1785
1787}
1788
1791 return EC;
1792
1796
1801 Names.push_back(std::string(Str));
1802 }
1803
1805}
1806
1809 return EC;
1810
1812 if (.readInt(NumFunctions))
1814
1816 for (uint32_t I = 0; I < NumFunctions; ++I)
1818 return EC;
1819
1822}
1823
1827 if (InlineStack.size() == 0)
1828 if (.readInt64(HeadCount))
1830
1834
1836
1838 if (.readInt(NumPosCounts))
1840
1842 if (.readInt(NumCallsites))
1844
1846 if (InlineStack.size() == 0) {
1847
1848
1849
1850
1851
1852
1856 Update = false;
1857 } else {
1858
1859
1860
1866 }
1868
1869 for (uint32_t I = 0; I < NumPosCounts; ++I) {
1873
1875 if (.readInt(NumTargets))
1877
1881
1882
1883
1884
1887
1891 if (Update) {
1892
1893
1894 for (auto *CallerProfile : NewStack)
1895 CallerProfile->addTotalSamples(Count);
1896
1897
1899 }
1900
1901
1902
1903
1904 for (uint32_t J = 0; J < NumTargets; J++) {
1908
1911
1913 if (.readInt64(TargetIdx))
1916
1918 if (.readInt64(TargetCount))
1920
1921 if (Update)
1924 TargetCount);
1925 }
1926 }
1927
1928
1929
1930 for (uint32_t I = 0; I < NumCallsites; I++) {
1931
1932
1933
1941 return EC;
1942 }
1943
1945}
1946
1947
1948
1949
1950
1953
1955 return EC;
1956
1957
1959 return EC;
1960
1962}
1963
1966 return Magic == "adcg*704";
1967}
1968
1970
1971
1972 if (Reader.useMD5()) {
1974 Reader.getBuffer()->getBufferIdentifier(),
1975 "Profile data remapping cannot be applied to profile data "
1976 "using MD5 names (original mangled names are not available).",
1978 return;
1979 }
1980
1981
1982
1983 assert(Remappings && "should be initialized while creating remapper");
1984 for (auto &Sample : Reader.getProfiles()) {
1986 Sample.second.findAllNames(NamesInSample);
1987 for (auto &Name : NamesInSample) {
1988 StringRef NameStr = Name.stringRef();
1989 if (auto Key = Remappings->insert(NameStr))
1990 NameMap.insert({Key, NameStr});
1991 }
1992 }
1993
1994 RemappingApplied = true;
1995}
1996
1997std::optional
1999 if (auto Key = Remappings->lookup(Fname)) {
2001 if (!Result.empty())
2002 return Result;
2003 }
2004 return std::nullopt;
2005}
2006
2007
2008
2009
2013 : FS.getBufferForFile(Filename);
2014 if (std::error_code EC = BufferOrErr.getError())
2015 return EC;
2016 auto Buffer = std::move(BufferOrErr.get());
2017
2018 return std::move(Buffer);
2019}
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032ErrorOr<std::unique_ptr>
2037 if (std::error_code EC = BufferOrError.getError())
2038 return EC;
2039 return create(BufferOrError.get(), C, FS, P, RemapFilename);
2040}
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2058 if (std::error_code EC = BufferOrError.getError())
2059 return EC;
2060 return create(BufferOrError.get(), Reader, C);
2061}
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2077 auto Remappings = std::make_unique();
2078 if (Error E = Remappings->read(*B)) {
2082 ParseError.getLineNum(),
2083 ParseError.getMessage()));
2084 });
2086 }
2087
2088 return std::make_unique(
2089 std::move(B), std::move(Remappings), Reader);
2090}
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2107 std::unique_ptr Reader;
2116 else
2118
2119 if (!RemapFilename.empty()) {
2121 RemapFilename, FS, *Reader, C);
2122 if (std::error_code EC = ReaderOrErr.getError()) {
2123 std::string Msg = "Could not create remapper: " + EC.message();
2125 return EC;
2126 }
2127 Reader->Remapper = std::move(ReaderOrErr.get());
2128 }
2129
2130 if (std::error_code EC = Reader->readHeader()) {
2131 return EC;
2132 }
2133
2134 Reader->setDiscriminatorMaskedBitFrom(P);
2135
2136 return std::move(Reader);
2137}
2138
2139
2140
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file defines the DenseMap class.
Provides ErrorOr smart pointer.
Module.h This file contains the declarations for the Module class.
This file supports working with JSON data.
static bool ParseHead(const StringRef &Input, StringRef &FName, uint64_t &NumSamples, uint64_t &NumHeadSamples)
Parse Input as function head.
Definition SampleProfReader.cpp:157
static void dumpFunctionProfileJson(const FunctionSamples &S, json::OStream &JOS, bool TopLevel=false)
Definition SampleProfReader.cpp:77
static bool isOffsetLegal(unsigned L)
Returns true if line offset L is legal (only has 16 bits).
Definition SampleProfReader.cpp:172
static bool ParseLine(const StringRef &Input, LineType &LineTy, uint32_t &Depth, uint64_t &NumSamples, uint32_t &LineOffset, uint32_t &Discriminator, StringRef &CalleeName, DenseMap< StringRef, uint64_t > &TargetCountMap, DenseMap< StringRef, uint64_t > &TypeCountMap, uint64_t &FunctionHash, uint32_t &Attributes, bool &IsFlat)
Parse Input as line sample.
Definition SampleProfReader.cpp:243
static cl::opt< bool > ProfileIsFSDisciminator("profile-isfs", cl::Hidden, cl::init(false), cl::desc("Profile uses flow sensitive discriminators"))
static std::string getSecFlagsStr(const SecHdrTableEntry &Entry)
Definition SampleProfReader.cpp:1552
static bool parseTypeCountMap(StringRef Input, DenseMap< StringRef, uint64_t > &TypeCountMap)
Definition SampleProfReader.cpp:205
static bool parseMetadata(const StringRef &Input, uint64_t &FunctionHash, uint32_t &Attributes)
Parse Input that contains metadata.
Definition SampleProfReader.cpp:181
LineType
Definition SampleProfReader.cpp:196
@ VirtualCallTypeProfile
Definition SampleProfReader.cpp:200
@ CallSiteProfile
Definition SampleProfReader.cpp:197
@ Metadata
Definition SampleProfReader.cpp:199
@ BodyProfile
Definition SampleProfReader.cpp:198
Defines the virtual file system interface vfs::FileSystem.
The Input class is used to parse a yaml document into in-memory structs and vectors.
Implements a dense probed hash-table based set.
Diagnostic information for the sample profiler.
Represents either an error or a value T.
Lightweight error class with error context and mandatory checking.
Tagged union holding either a T or a Error.
static LLVM_ABI GUID getGUIDAssumingExternalLinkage(StringRef GlobalName)
Return a 64-bit global unique ID constructed from the name of a global symbol.
This is an important class for using LLVM in a threaded context.
This interface provides simple read-only access to a block of memory, and provides simple methods for...
static ErrorOr< std::unique_ptr< MemoryBuffer > > getSTDIN()
Read all of stdin into a file buffer, and return it.
static LLVM_ABI const ArrayRef< uint32_t > DefaultCutoffs
A vector of useful cutoff values for detailed summary.
void push_back(const T &Elt)
StringRef - Represent a constant reference to a string, i.e.
static constexpr size_t npos
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr bool empty() const
empty - Check if the string is empty.
constexpr size_t size() const
size - Get the string size.
size_t find_last_of(char C, size_t From=npos) const
Find the last character in the string that is C, or npos if not found.
size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
LLVM_ABI size_t find_first_not_of(char C, size_t From=0) const
Find the first character in the string that is not C or npos if not found.
Target - Wrapper for Target specific information.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
json::OStream allows writing well-formed JSON without materializing all structures as json::Value ahe...
void object(Block Contents)
Emit an object whose elements are emitted in the provided Block.
void attribute(llvm::StringRef Key, const Value &Contents)
Emit an attribute whose value is self-contained (number, vector etc).
LLVM_ABI void arrayBegin()
void attributeArray(llvm::StringRef Key, Block Contents)
Emit an attribute whose value is an array with elements from the Block.
A forward iterator which reads text lines from a buffer.
int64_t line_number() const
Return the current line number. May return any number at EOF.
bool is_at_eof() const
Return true if we've reached EOF or are an "end" iterator.
This class implements an extremely fast bulk output stream that can only output to a stream.
This class represents a function that is read from a sample profile.
StringRef stringRef() const
Convert to StringRef.
uint64_t getHashCode() const
Get hash code of this object.
std::string str() const
Convert to a string, usually for output purpose.
Representation of the samples collected for a function.
static LLVM_ABI bool ProfileIsPreInlined
sampleprof_error addTotalSamples(uint64_t Num, uint64_t Weight=1)
uint64_t getHeadSamples() const
For top-level functions, return the total number of branch samples that have the function as the bran...
void setFunction(FunctionId NewFunctionID)
Set the name of the function.
static LLVM_ABI bool ProfileIsCS
FunctionId getFunction() const
Return the function name.
sampleprof_error addHeadSamples(uint64_t Num, uint64_t Weight=1)
sampleprof_error addCalledTargetSamples(uint32_t LineOffset, uint32_t Discriminator, FunctionId Func, uint64_t Num, uint64_t Weight=1)
FunctionSamplesMap & functionSamplesAt(const LineLocation &Loc)
Return the function samples at the given callsite location.
static LLVM_ABI bool ProfileIsProbeBased
static StringRef getCanonicalFnName(const Function &F)
Return the canonical name for a function, taking into account suffix elision policy attributes.
sampleprof_error addBodySamples(uint32_t LineOffset, uint32_t Discriminator, uint64_t Num, uint64_t Weight=1)
void setFunctionHash(uint64_t Hash)
static LLVM_ABI bool ProfileIsFS
If this profile uses flow sensitive discriminators.
SampleContext & getContext() const
static LLVM_ABI bool HasUniqSuffix
Whether the profile contains any ".__uniq." suffix in a name.
uint64_t getTotalSamples() const
Return the total number of samples collected inside the function.
const CallsiteSampleMap & getCallsiteSamples() const
Return all the callsite samples collected in the body of the function.
void setContext(const SampleContext &FContext)
TypeCountMap & getTypeSamplesAt(const LineLocation &Loc)
Returns the vtable access samples for the C++ types for Loc.
const BodySampleMap & getBodySamples() const
Return all the samples collected in the body of the function.
void setAllAttributes(uint32_t A)
FunctionId getFunction() const
bool isPrefixOf(const SampleContext &That) const
This class provides operator overloads to the map container using MD5 as the key type,...
iterator find(const SampleContext &Ctx)
std::error_code readProfile(FunctionSamples &FProfile)
Read the contents of the given profile instance.
Definition SampleProfReader.cpp:713
std::error_code readNameTable()
Read the whole name table.
Definition SampleProfReader.cpp:1233
const uint8_t * Data
Points to the current location in the buffer.
ErrorOr< StringRef > readString()
Read a string from the profile.
Definition SampleProfReader.cpp:565
std::vector< FunctionId > NameTable
Function name table.
ErrorOr< T > readNumber()
Read a numeric value of type T from the profile.
Definition SampleProfReader.cpp:547
ErrorOr< SampleContextFrames > readContextFromTable(size_t *RetIdx=nullptr)
Read a context indirectly via the CSNameTable.
Definition SampleProfReader.cpp:611
ErrorOr< std::pair< SampleContext, uint64_t > > readSampleContextFromTable()
Read a context indirectly via the CSNameTable if the profile has context, otherwise same as readStrin...
Definition SampleProfReader.cpp:623
std::error_code readHeader() override
Read and validate the file header.
Definition SampleProfReader.cpp:1639
const uint64_t * MD5SampleContextStart
The starting address of the table of MD5 values of sample contexts.
std::vector< SampleContextFrameVector > CSNameTable
CSNameTable is used to save full context vectors.
std::error_code readImpl() override
Read sample profiles from the associated file.
Definition SampleProfReader.cpp:830
ErrorOr< FunctionId > readStringFromTable(size_t *RetIdx=nullptr)
Read a string indirectly via the name table. Optionally return the index.
Definition SampleProfReader.cpp:601
std::vector< uint64_t > MD5SampleContextTable
Table to cache MD5 values of sample contexts corresponding to readSampleContextFromTable(),...
std::error_code readCallsiteVTableProf(FunctionSamples &FProfile)
Read all virtual functions' vtable access counts for FProfile.
Definition SampleProfReader.cpp:681
ErrorOr< size_t > readStringIndex(T &Table)
Read the string index and check whether it overflows the table.
Definition SampleProfReader.cpp:591
const uint8_t * End
Points to the end of the buffer.
ErrorOr< T > readUnencodedNumber()
Read a numeric value of type T from the profile.
Definition SampleProfReader.cpp:578
std::error_code readFuncProfile(const uint8_t *Start)
Read the next function profile instance.
Definition SampleProfReader.cpp:826
std::error_code readVTableTypeCountMap(TypeCountMap &M)
Read bytes from the input buffer pointed by Data and decode them into M.
Definition SampleProfReader.cpp:652
std::error_code readSummary()
Read profile summary.
Definition SampleProfReader.cpp:1672
std::error_code readMagicIdent()
Read the contents of Magic number and Version number.
Definition SampleProfReader.cpp:1621
std::error_code readFuncOffsetTable()
Definition SampleProfReader.cpp:979
std::vector< SecHdrTableEntry > SecHdrTable
bool collectFuncsFromModule() override
Collect functions with definitions in Module M.
Definition SampleProfReader.cpp:970
uint64_t getSectionSize(SecType Type)
Get the total size of all Type sections.
Definition SampleProfReader.cpp:1530
std::error_code readCSNameTableSec()
Definition SampleProfReader.cpp:1333
virtual std::error_code readCustomSection(const SecHdrTableEntry &Entry)=0
std::vector< std::pair< SampleContext, uint64_t > > FuncOffsetList
The list version of FuncOffsetTable.
DenseSet< StringRef > FuncsToUse
The set containing the functions to use when compiling a module.
std::unique_ptr< ProfileSymbolList > ProfSymList
std::error_code readSecHdrTable()
Definition SampleProfReader.cpp:1503
std::error_code readFuncProfiles()
Definition SampleProfReader.cpp:1107
bool useFuncOffsetList() const
Determine which container readFuncOffsetTable() should populate, the list FuncOffsetList or the map F...
Definition SampleProfReader.cpp:918
std::error_code readNameTableSec(bool IsMD5, bool FixedLengthMD5)
Definition SampleProfReader.cpp:1274
std::error_code readSecHdrTableEntry(uint64_t Idx)
Definition SampleProfReader.cpp:1476
std::error_code readImpl() override
Read sample profiles in extensible format from the associated file.
Definition SampleProfReader.cpp:1175
std::error_code readFuncMetadata(bool ProfileHasAttribute, DenseSet< FunctionSamples * > &Profiles)
Definition SampleProfReader.cpp:1433
virtual std::error_code readOneSection(const uint8_t *Start, uint64_t Size, const SecHdrTableEntry &Entry)
Definition SampleProfReader.cpp:841
bool dumpSectionInfo(raw_ostream &OS=dbgs()) override
Definition SampleProfReader.cpp:1602
DenseMap< hash_code, uint64_t > FuncOffsetTable
The table mapping from a function context's MD5 to the offset of its FunctionSample towards file star...
std::error_code readHeader() override
Read and validate the file header.
Definition SampleProfReader.cpp:1515
uint64_t getFileSize()
Get the total size of header and all sections.
Definition SampleProfReader.cpp:1539
std::error_code readProfileSymbolList()
Definition SampleProfReader.cpp:1137
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if Buffer is in the format supported by this class.
Definition SampleProfReader.cpp:1717
ErrorOr< T > readNumber()
Definition SampleProfReader.cpp:1731
GCOVBuffer GcovBuffer
GCOV buffer containing the profile.
std::vector< std::string > Names
Function names in this profile.
std::error_code readImpl() override
Read sample profiles from the associated file.
Definition SampleProfReader.cpp:1951
std::error_code readNameTable()
Definition SampleProfReader.cpp:1789
std::error_code readHeader() override
Read and validate the file header.
Definition SampleProfReader.cpp:1754
ErrorOr< StringRef > readString()
Definition SampleProfReader.cpp:1747
static const uint32_t GCOVTagAFDOFunction
std::error_code readOneFunctionProfile(const InlineCallStack &InlineStack, bool Update, uint32_t Offset)
Definition SampleProfReader.cpp:1824
std::error_code readFunctionProfiles()
Definition SampleProfReader.cpp:1807
static const uint32_t GCOVTagAFDOFileNames
GCOV tags used to separate sections in the profile file.
std::error_code skipNextWord()
Definition SampleProfReader.cpp:1724
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if Buffer is in the format supported by this class.
Definition SampleProfReader.cpp:1964
std::error_code readSectionTag(uint32_t Expected)
Read the section tag and check that it's the same as Expected.
Definition SampleProfReader.cpp:1775
static LLVM_ABI ErrorOr< std::unique_ptr< SampleProfileReaderItaniumRemapper > > create(StringRef Filename, vfs::FileSystem &FS, SampleProfileReader &Reader, LLVMContext &C)
Create a remapper from the given remapping file.
Definition SampleProfReader.cpp:2053
LLVM_ABI void applyRemapping(LLVMContext &Ctx)
Apply remappings to the profile read by Reader.
Definition SampleProfReader.cpp:1969
LLVM_ABI std::optional< StringRef > lookUpNameInProfile(StringRef FunctionName)
Return the equivalent name in the profile for FunctionName if it exists.
Definition SampleProfReader.cpp:1998
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if Buffer is in the format supported by this class.
Definition SampleProfReader.cpp:1710
std::error_code readImpl() override
Read sample profiles from the associated file.
Definition SampleProfReader.cpp:359
static bool hasFormat(const MemoryBuffer &Buffer)
Return true if Buffer is in the format supported by this class.
Definition SampleProfReader.cpp:531
Sample-based profile reader.
std::pair< const uint8_t *, const uint8_t * > ProfileSecRange
bool ReadVTableProf
If true, the profile has vtable profiles and reader should decode them to parse profiles correctly.
bool ProfileIsPreInlined
Whether function profile contains ShouldBeInlined contexts.
std::unordered_map< uint64_t, std::pair< const uint8_t *, const uint8_t * > > FuncMetadataIndex
uint32_t CSProfileCount
Number of context-sensitive profiles.
static LLVM_ABI ErrorOr< std::unique_ptr< SampleProfileReader > > create(StringRef Filename, LLVMContext &C, vfs::FileSystem &FS, FSDiscriminatorPass P=FSDiscriminatorPass::Base, StringRef RemapFilename="")
Create a sample profile reader appropriate to the file format.
Definition SampleProfReader.cpp:2033
LLVM_ABI void dump(raw_ostream &OS=dbgs())
Print all the profiles on stream OS.
Definition SampleProfReader.cpp:70
bool useMD5() const
Return whether names in the profile are all MD5 numbers.
const Module * M
The current module being compiled if SampleProfileReader is used by compiler.
std::unique_ptr< MemoryBuffer > Buffer
Memory buffer holding the profile file.
std::unique_ptr< SampleProfileReaderItaniumRemapper > Remapper
bool ProfileHasAttribute
Whether the profile has attribute metadata.
bool SkipFlatProf
If SkipFlatProf is true, skip functions marked with !Flat in text mode or sections with SecFlagFlat f...
std::error_code read()
The interface to read sample profiles from the associated file.
bool ProfileIsCS
Whether function profiles are context-sensitive flat profiles.
bool ProfileIsMD5
Whether the profile uses MD5 for Sample Contexts and function names.
std::unique_ptr< ProfileSummary > Summary
Profile summary information.
LLVM_ABI void computeSummary()
Compute summary for this profile.
Definition SampleProfReader.cpp:2141
uint32_t getDiscriminatorMask() const
Get the bitmask the discriminators: For FS profiles, return the bit mask for this pass.
bool ProfileIsFS
Whether the function profiles use FS discriminators.
LLVM_ABI void dumpJson(raw_ostream &OS=dbgs())
Print all the profiles on stream OS in the JSON format.
Definition SampleProfReader.cpp:137
SampleProfileMap Profiles
Map every function to its associated profile.
LLVM_ABI void dumpFunctionProfile(const FunctionSamples &FS, raw_ostream &OS=dbgs())
Print the profile for FunctionSamples on stream OS.
Definition SampleProfReader.cpp:64
bool ProfileIsProbeBased
Whether samples are collected based on pseudo probes.
void reportError(int64_t LineNumber, const Twine &Msg) const
Report a parse error message.
LLVMContext & Ctx
LLVM context used to emit diagnostics.
Representation of a single sample record.
uint64_t getSamples() const
const SortedCallTargetSet getSortedCallTargets() const
The virtual file system interface.
@ C
The default llvm calling convention, compatible with C.
initializer< Ty > init(const Ty &Val)
LLVM_ABI Error decompress(ArrayRef< uint8_t > Input, uint8_t *Output, size_t &UncompressedSize)
LLVM_ABI bool isAvailable()
LLVM_ABI void sortFuncProfiles(const SampleProfileMap &ProfileMap, std::vector< NameFunctionSamples > &SortedProfiles)
static uint64_t SPMagic(SampleProfileFormat Format=SPF_Binary)
std::map< LineLocation, FunctionSamplesMap > CallsiteSampleMap
static bool hasSecFlag(const SecHdrTableEntry &Entry, SecFlagType Flag)
@ HIST_TYPE_INDIR_CALL_TOPN
uint64_t MD5Hash(const FunctionId &Obj)
@ SecFlagIsPreInlined
SecFlagIsPreInlined means this profile contains ShouldBeInlined contexts thus this is CS preinliner c...
@ SecFlagHasVTableTypeProf
SecFlagHasVTableTypeProf means this profile contains vtable type profiles.
@ SecFlagPartial
SecFlagPartial means the profile is for common/shared code.
@ SecFlagFSDiscriminator
SecFlagFSDiscriminator means this profile uses flow-sensitive discriminators.
@ SecFlagFullContext
SecFlagContext means this is context-sensitive flat profile for CSSPGO.
SmallVector< SampleContextFrame, 1 > SampleContextFrameVector
std::map< FunctionId, uint64_t > TypeCountMap
Key represents type of a C++ polymorphic class type by its vtable and value represents its counter.
static std::string getSecName(SecType Type)
constexpr char kVTableProfPrefix[]
SmallVector< FunctionSamples *, 10 > InlineCallStack
static uint64_t SPVersion()
std::map< LineLocation, SampleRecord > BodySampleMap
uint64_t read64le(const void *P)
void write64le(void *P, uint64_t V)
value_type read(const void *memory, endianness endian)
Read a value of a particular endianness from memory.
value_type readNext(const CharT *&memory, endianness endian)
Read a value of a particular endianness from a buffer, and increment the buffer past that value.
This is an optimization pass for GlobalISel generic memory operations.
static Expected< std::unique_ptr< MemoryBuffer > > setupMemoryBuffer(const Twine &Filename, vfs::FileSystem &FS)
void handleAllErrors(Error E, HandlerTs &&... Handlers)
Behaves the same as handleErrors, except that by contract all errors must be handled by the given han...
uint64_t decodeULEB128(const uint8_t *p, unsigned *n=nullptr, const uint8_t *end=nullptr, const char **error=nullptr)
Utility function to decode a ULEB128 value.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
FunctionAddr VTableAddr uintptr_t uintptr_t Version
sampleprof_error mergeSampleProfErrors(sampleprof_error &Accumulator, sampleprof_error Result)
bool isDigit(char C)
Checks if character C is one of the 10 decimal digits.
FunctionAddr VTableAddr Count
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
ArrayRef(const T &OneElt) -> ArrayRef< T >
Represents the relative location of an instruction.