@@ -987,6 +987,10 @@ class ModuleSummaryIndexBitcodeReader : public BitcodeReaderBase {
987
987
/// ids from the lists in the callsite and alloc entries to the index.
988
988
std::vector<uint64_t> StackIds;
989
989
990
+ /// Linearized radix tree of allocation contexts. See the description above
991
+ /// the CallStackRadixTreeBuilder class in ProfileData/MemProf.h for format.
992
+ std::vector<uint64_t> RadixArray;
993
+
990
994
public:
991
995
ModuleSummaryIndexBitcodeReader(
992
996
BitstreamCursor Stream, StringRef Strtab, ModuleSummaryIndex &TheIndex,
@@ -1013,6 +1017,8 @@ class ModuleSummaryIndexBitcodeReader : public BitcodeReaderBase {
1013
1017
TypeIdCompatibleVtableInfo &TypeId);
1014
1018
std::vector<FunctionSummary::ParamAccess>
1015
1019
parseParamAccesses(ArrayRef<uint64_t> Record);
1020
+ SmallVector<unsigned> parseAllocInfoContext(ArrayRef<uint64_t> Record,
1021
+ unsigned &I);
1016
1022
1017
1023
template <bool AllowNullValueInfo = false>
1018
1024
std::pair<ValueInfo, GlobalValue::GUID>
@@ -7544,6 +7550,48 @@ void ModuleSummaryIndexBitcodeReader::parseTypeIdCompatibleVtableSummaryRecord(
7544
7550
parseTypeIdCompatibleVtableInfo(Record, Slot, TypeId);
7545
7551
}
7546
7552
7553
+ SmallVector<unsigned> ModuleSummaryIndexBitcodeReader::parseAllocInfoContext(
7554
+ ArrayRef<uint64_t> Record, unsigned &I) {
7555
+ SmallVector<unsigned> StackIdList;
7556
+ // For backwards compatibility with old format before radix tree was
7557
+ // used, simply see if we found a radix tree array record (and thus if
7558
+ // the RadixArray is non-empty).
7559
+ if (RadixArray.empty()) {
7560
+ unsigned NumStackEntries = Record[I++];
7561
+ assert(Record.size() - I >= NumStackEntries);
7562
+ StackIdList.reserve(NumStackEntries);
7563
+ for (unsigned J = 0; J < NumStackEntries; J++) {
7564
+ assert(Record[I] < StackIds.size());
7565
+ StackIdList.push_back(
7566
+ TheIndex.addOrGetStackIdIndex(StackIds[Record[I++]]));
7567
+ }
7568
+ } else {
7569
+ unsigned RadixIndex = Record[I++];
7570
+ // See the comments above CallStackRadixTreeBuilder in ProfileData/MemProf.h
7571
+ // for a detailed description of the radix tree array format. Briefly, the
7572
+ // first entry will be the number of frames, any negative values are the
7573
+ // negative of the offset of the next frame, and otherwise the frames are in
7574
+ // increasing linear order.
7575
+ assert(RadixIndex < RadixArray.size());
7576
+ unsigned NumStackIds = RadixArray[RadixIndex++];
7577
+ StackIdList.reserve(NumStackIds);
7578
+ while (NumStackIds--) {
7579
+ assert(RadixIndex < RadixArray.size());
7580
+ unsigned Elem = RadixArray[RadixIndex];
7581
+ if (static_cast<std::make_signed_t<unsigned>>(Elem) < 0) {
7582
+ RadixIndex = RadixIndex - Elem;
7583
+ assert(RadixIndex < RadixArray.size());
7584
+ Elem = RadixArray[RadixIndex];
7585
+ // We shouldn't encounter a second offset in a row.
7586
+ assert(static_cast<std::make_signed_t<unsigned>>(Elem) >= 0);
7587
+ }
7588
+ RadixIndex++;
7589
+ StackIdList.push_back(TheIndex.addOrGetStackIdIndex(StackIds[Elem]));
7590
+ }
7591
+ }
7592
+ return StackIdList;
7593
+ }
7594
+
7547
7595
static void setSpecialRefs(SmallVectorImpl<ValueInfo> &Refs, unsigned ROCnt,
7548
7596
unsigned WOCnt) {
7549
7597
// Readonly and writeonly refs are in the end of the refs list.
@@ -8010,6 +8058,11 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) {
8010
8058
break;
8011
8059
}
8012
8060
8061
+ case bitc::FS_CONTEXT_RADIX_TREE_ARRAY: { // [n x entry]
8062
+ RadixArray = ArrayRef<uint64_t>(Record);
8063
+ break;
8064
+ }
8065
+
8013
8066
case bitc::FS_PERMODULE_CALLSITE_INFO: {
8014
8067
unsigned ValueID = Record[0];
8015
8068
SmallVector<unsigned> StackIdList;
@@ -8065,14 +8118,7 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) {
8065
8118
(Version < 10 && I < Record.size())) {
8066
8119
assert(Record.size() - I >= 2);
8067
8120
AllocationType AllocType = (AllocationType)Record[I++];
8068
- unsigned NumStackEntries = Record[I++];
8069
- assert(Record.size() - I >= NumStackEntries);
8070
- SmallVector<unsigned> StackIdList;
8071
- for (unsigned J = 0; J < NumStackEntries; J++) {
8072
- assert(Record[I] < StackIds.size());
8073
- StackIdList.push_back(
8074
- TheIndex.addOrGetStackIdIndex(StackIds[Record[I++]]));
8075
- }
8121
+ auto StackIdList = parseAllocInfoContext(Record, I);
8076
8122
MIBs.push_back(MIBInfo(AllocType, std::move(StackIdList)));
8077
8123
}
8078
8124
// We either have nothing left or at least NumMIBs context size info
@@ -8123,14 +8169,7 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) {
8123
8169
while (MIBsRead++ < NumMIBs) {
8124
8170
assert(Record.size() - I >= 2);
8125
8171
AllocationType AllocType = (AllocationType)Record[I++];
8126
- unsigned NumStackEntries = Record[I++];
8127
- assert(Record.size() - I >= NumStackEntries);
8128
- SmallVector<unsigned> StackIdList;
8129
- for (unsigned J = 0; J < NumStackEntries; J++) {
8130
- assert(Record[I] < StackIds.size());
8131
- StackIdList.push_back(
8132
- TheIndex.addOrGetStackIdIndex(StackIds[Record[I++]]));
8133
- }
8172
+ auto StackIdList = parseAllocInfoContext(Record, I);
8134
8173
MIBs.push_back(MIBInfo(AllocType, std::move(StackIdList)));
8135
8174
}
8136
8175
assert(Record.size() - I >= NumVersions);
0 commit comments