From 776476c282bca71d5b856e80e0a88fbd6f3ccdd2 Mon Sep 17 00:00:00 2001 From: Teresa Johnson Date: Fri, 22 Nov 2024 16:18:30 -0800 Subject: Reapply "[MemProf] Use radix tree for alloc contexts in bitcode summaries" (#117395) (#117404) This reverts commit fdb050a5024320ec29d2edf3f2bc686c3a84abaa, and restores ccb4702038900d82d1041ff610788740f5cef723, with a fix for build bot failures. Specifically, add ProfileData to the dependences of the BitWriter library, which was causing shared library builds of LLVM to fail. Reproduced the failure with a shared library build and confirmed this change fixes that build failure. --- llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 71 ++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 16 deletions(-) (limited to 'llvm/lib/Bitcode/Reader/BitcodeReader.cpp') diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 3e6abac..11fbe6e 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -987,6 +987,10 @@ class ModuleSummaryIndexBitcodeReader : public BitcodeReaderBase { /// ids from the lists in the callsite and alloc entries to the index. std::vector StackIds; + /// Linearized radix tree of allocation contexts. See the description above + /// the CallStackRadixTreeBuilder class in ProfileData/MemProf.h for format. + std::vector RadixArray; + public: ModuleSummaryIndexBitcodeReader( BitstreamCursor Stream, StringRef Strtab, ModuleSummaryIndex &TheIndex, @@ -1013,6 +1017,8 @@ private: TypeIdCompatibleVtableInfo &TypeId); std::vector parseParamAccesses(ArrayRef Record); + SmallVector parseAllocInfoContext(ArrayRef Record, + unsigned &I); template std::pair @@ -7544,6 +7550,48 @@ void ModuleSummaryIndexBitcodeReader::parseTypeIdCompatibleVtableSummaryRecord( parseTypeIdCompatibleVtableInfo(Record, Slot, TypeId); } +SmallVector ModuleSummaryIndexBitcodeReader::parseAllocInfoContext( + ArrayRef Record, unsigned &I) { + SmallVector StackIdList; + // For backwards compatibility with old format before radix tree was + // used, simply see if we found a radix tree array record (and thus if + // the RadixArray is non-empty). + if (RadixArray.empty()) { + unsigned NumStackEntries = Record[I++]; + assert(Record.size() - I >= NumStackEntries); + StackIdList.reserve(NumStackEntries); + for (unsigned J = 0; J < NumStackEntries; J++) { + assert(Record[I] < StackIds.size()); + StackIdList.push_back( + TheIndex.addOrGetStackIdIndex(StackIds[Record[I++]])); + } + } else { + unsigned RadixIndex = Record[I++]; + // See the comments above CallStackRadixTreeBuilder in ProfileData/MemProf.h + // for a detailed description of the radix tree array format. Briefly, the + // first entry will be the number of frames, any negative values are the + // negative of the offset of the next frame, and otherwise the frames are in + // increasing linear order. + assert(RadixIndex < RadixArray.size()); + unsigned NumStackIds = RadixArray[RadixIndex++]; + StackIdList.reserve(NumStackIds); + while (NumStackIds--) { + assert(RadixIndex < RadixArray.size()); + unsigned Elem = RadixArray[RadixIndex]; + if (static_cast>(Elem) < 0) { + RadixIndex = RadixIndex - Elem; + assert(RadixIndex < RadixArray.size()); + Elem = RadixArray[RadixIndex]; + // We shouldn't encounter a second offset in a row. + assert(static_cast>(Elem) >= 0); + } + RadixIndex++; + StackIdList.push_back(TheIndex.addOrGetStackIdIndex(StackIds[Elem])); + } + } + return StackIdList; +} + static void setSpecialRefs(SmallVectorImpl &Refs, unsigned ROCnt, unsigned WOCnt) { // Readonly and writeonly refs are in the end of the refs list. @@ -8010,6 +8058,11 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { break; } + case bitc::FS_CONTEXT_RADIX_TREE_ARRAY: { // [n x entry] + RadixArray = ArrayRef(Record); + break; + } + case bitc::FS_PERMODULE_CALLSITE_INFO: { unsigned ValueID = Record[0]; SmallVector StackIdList; @@ -8065,14 +8118,7 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { (Version < 10 && I < Record.size())) { assert(Record.size() - I >= 2); AllocationType AllocType = (AllocationType)Record[I++]; - unsigned NumStackEntries = Record[I++]; - assert(Record.size() - I >= NumStackEntries); - SmallVector StackIdList; - for (unsigned J = 0; J < NumStackEntries; J++) { - assert(Record[I] < StackIds.size()); - StackIdList.push_back( - TheIndex.addOrGetStackIdIndex(StackIds[Record[I++]])); - } + auto StackIdList = parseAllocInfoContext(Record, I); MIBs.push_back(MIBInfo(AllocType, std::move(StackIdList))); } // We either have nothing left or at least NumMIBs context size info @@ -8123,14 +8169,7 @@ Error ModuleSummaryIndexBitcodeReader::parseEntireSummary(unsigned ID) { while (MIBsRead++ < NumMIBs) { assert(Record.size() - I >= 2); AllocationType AllocType = (AllocationType)Record[I++]; - unsigned NumStackEntries = Record[I++]; - assert(Record.size() - I >= NumStackEntries); - SmallVector StackIdList; - for (unsigned J = 0; J < NumStackEntries; J++) { - assert(Record[I] < StackIds.size()); - StackIdList.push_back( - TheIndex.addOrGetStackIdIndex(StackIds[Record[I++]])); - } + auto StackIdList = parseAllocInfoContext(Record, I); MIBs.push_back(MIBInfo(AllocType, std::move(StackIdList))); } assert(Record.size() - I >= NumVersions); -- cgit v1.1