diff options
Diffstat (limited to 'llvm/lib/Bitcode/Writer/BitcodeWriter.cpp')
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 158 |
1 files changed, 11 insertions, 147 deletions
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 8f22a50..59e070a 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -60,7 +60,6 @@ #include "llvm/MC/StringTableBuilder.h" #include "llvm/MC/TargetRegistry.h" #include "llvm/Object/IRSymtab.h" -#include "llvm/ProfileData/MemProf.h" #include "llvm/Support/AtomicOrdering.h" #include "llvm/Support/Casting.h" #include "llvm/Support/CommandLine.h" @@ -84,7 +83,6 @@ #include <vector> using namespace llvm; -using namespace llvm::memprof; static cl::opt<unsigned> IndexThreshold("bitcode-mdindex-threshold", cl::Hidden, cl::init(25), @@ -233,8 +231,7 @@ private: SmallVector<uint64_t, 64> &NameVals, GlobalValueSummary *Summary, unsigned ValueID, unsigned FSCallsAbbrev, unsigned FSCallsProfileAbbrev, unsigned CallsiteAbbrev, unsigned AllocAbbrev, unsigned ContextIdAbbvId, - const Function &F, DenseMap<CallStackId, LinearCallStackId> &CallStackPos, - CallStackId &CallStackCount); + const Function &F); void writeModuleLevelReferences(const GlobalVariable &V, SmallVector<uint64_t, 64> &NameVals, unsigned FSModRefsAbbrev, @@ -4198,58 +4195,12 @@ static void writeTypeIdCompatibleVtableSummaryRecord( } } -// Adds the allocation contexts to the CallStacks map. We simply use the -// size at the time the context was added as the CallStackId. This works because -// when we look up the call stacks later on we process the function summaries -// and their allocation records in the same exact order. -static void collectMemProfCallStacks( - FunctionSummary *FS, std::function<LinearFrameId(unsigned)> GetStackIndex, - MapVector<CallStackId, llvm::SmallVector<LinearFrameId>> &CallStacks) { - // The interfaces in ProfileData/MemProf.h use a type alias for a stack frame - // id offset into the index of the full stack frames. The ModuleSummaryIndex - // currently uses unsigned. Make sure these stay in sync. - static_assert(std::is_same_v<LinearFrameId, unsigned>); - for (auto &AI : FS->allocs()) { - for (auto &MIB : AI.MIBs) { - SmallVector<unsigned> StackIdIndices; - StackIdIndices.reserve(MIB.StackIdIndices.size()); - for (auto Id : MIB.StackIdIndices) - StackIdIndices.push_back(GetStackIndex(Id)); - // The CallStackId is the size at the time this context was inserted. - CallStacks.insert({CallStacks.size(), StackIdIndices}); - } - } -} - -// Build the radix tree from the accumulated CallStacks, write out the resulting -// linearized radix tree array, and return the map of call stack positions into -// this array for use when writing the allocation records. The returned map is -// indexed by a CallStackId which in this case is implicitly determined by the -// order of function summaries and their allocation infos being written. -static DenseMap<CallStackId, LinearCallStackId> writeMemoryProfileRadixTree( - MapVector<CallStackId, llvm::SmallVector<LinearFrameId>> &&CallStacks, - BitstreamWriter &Stream, unsigned RadixAbbrev) { - assert(!CallStacks.empty()); - DenseMap<unsigned, FrameStat> FrameHistogram = - computeFrameHistogram<LinearFrameId>(CallStacks); - CallStackRadixTreeBuilder<LinearFrameId> Builder; - // We don't need a MemProfFrameIndexes map as we have already converted the - // full stack id hash to a linear offset into the StackIds array. - Builder.build(std::move(CallStacks), /*MemProfFrameIndexes=*/std::nullopt, - FrameHistogram); - Stream.EmitRecord(bitc::FS_CONTEXT_RADIX_TREE_ARRAY, Builder.getRadixArray(), - RadixAbbrev); - return Builder.takeCallStackPos(); -} - static void writeFunctionHeapProfileRecords( BitstreamWriter &Stream, FunctionSummary *FS, unsigned CallsiteAbbrev, unsigned AllocAbbrev, unsigned ContextIdAbbvId, bool PerModule, std::function<unsigned(const ValueInfo &VI)> GetValueID, std::function<unsigned(unsigned)> GetStackIndex, - bool WriteContextSizeInfoIndex, - DenseMap<CallStackId, LinearCallStackId> &CallStackPos, - CallStackId &CallStackCount) { + bool WriteContextSizeInfoIndex) { SmallVector<uint64_t> Record; for (auto &CI : FS->callsites()) { @@ -4283,9 +4234,9 @@ static void writeFunctionHeapProfileRecords( Record.push_back(AI.Versions.size()); for (auto &MIB : AI.MIBs) { Record.push_back((uint8_t)MIB.AllocType); - // Record the index into the radix tree array for this context. - assert(CallStackCount <= CallStackPos.size()); - Record.push_back(CallStackPos[CallStackCount++]); + Record.push_back(MIB.StackIdIndices.size()); + for (auto Id : MIB.StackIdIndices) + Record.push_back(GetStackIndex(Id)); } if (!PerModule) { for (auto V : AI.Versions) @@ -4331,9 +4282,7 @@ void ModuleBitcodeWriterBase::writePerModuleFunctionSummaryRecord( SmallVector<uint64_t, 64> &NameVals, GlobalValueSummary *Summary, unsigned ValueID, unsigned FSCallsRelBFAbbrev, unsigned FSCallsProfileAbbrev, unsigned CallsiteAbbrev, - unsigned AllocAbbrev, unsigned ContextIdAbbvId, const Function &F, - DenseMap<CallStackId, LinearCallStackId> &CallStackPos, - CallStackId &CallStackCount) { + unsigned AllocAbbrev, unsigned ContextIdAbbvId, const Function &F) { NameVals.push_back(ValueID); FunctionSummary *FS = cast<FunctionSummary>(Summary); @@ -4348,7 +4297,7 @@ void ModuleBitcodeWriterBase::writePerModuleFunctionSummaryRecord( /*PerModule*/ true, /*GetValueId*/ [&](const ValueInfo &VI) { return getValueId(VI); }, /*GetStackIndex*/ [&](unsigned I) { return I; }, - /*WriteContextSizeInfoIndex*/ true, CallStackPos, CallStackCount); + /*WriteContextSizeInfoIndex*/ true); auto SpecialRefCnts = FS->specialRefCounts(); NameVals.push_back(getEncodedGVSummaryFlags(FS->flags())); @@ -4581,54 +4530,12 @@ void ModuleBitcodeWriterBase::writePerModuleGlobalValueSummary() { Abbv = std::make_shared<BitCodeAbbrev>(); Abbv->Add(BitCodeAbbrevOp(bitc::FS_PERMODULE_ALLOC_INFO)); Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // nummib - // n x (alloc type, context radix tree index) + // n x (alloc type, numstackids, numstackids x stackidindex) // optional: nummib x (numcontext x total size) Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); unsigned AllocAbbrev = Stream.EmitAbbrev(std::move(Abbv)); - Abbv = std::make_shared<BitCodeAbbrev>(); - Abbv->Add(BitCodeAbbrevOp(bitc::FS_CONTEXT_RADIX_TREE_ARRAY)); - // n x entry - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); - unsigned RadixAbbrev = Stream.EmitAbbrev(std::move(Abbv)); - - // First walk through all the functions and collect the allocation contexts in - // their associated summaries, for use in constructing a radix tree of - // contexts. Note that we need to do this in the same order as the functions - // are processed further below since the call stack positions in the resulting - // radix tree array are identified based on this order. - MapVector<CallStackId, llvm::SmallVector<LinearFrameId>> CallStacks; - for (const Function &F : M) { - // Summary emission does not support anonymous functions, they have to be - // renamed using the anonymous function renaming pass. - if (!F.hasName()) - report_fatal_error("Unexpected anonymous function when writing summary"); - - ValueInfo VI = Index->getValueInfo(F.getGUID()); - if (!VI || VI.getSummaryList().empty()) { - // Only declarations should not have a summary (a declaration might - // however have a summary if the def was in module level asm). - assert(F.isDeclaration()); - continue; - } - auto *Summary = VI.getSummaryList()[0].get(); - FunctionSummary *FS = cast<FunctionSummary>(Summary); - collectMemProfCallStacks( - FS, /*GetStackIndex*/ [](unsigned I) { return I; }, CallStacks); - } - // Finalize the radix tree, write it out, and get the map of positions in the - // linearized tree array. - DenseMap<CallStackId, LinearCallStackId> CallStackPos; - if (!CallStacks.empty()) { - CallStackPos = - writeMemoryProfileRadixTree(std::move(CallStacks), Stream, RadixAbbrev); - } - - // Keep track of the current index into the CallStackPos map. - CallStackId CallStackCount = 0; - SmallVector<uint64_t, 64> NameVals; // Iterate over the list of functions instead of the Index to // ensure the ordering is stable. @@ -4648,8 +4555,7 @@ void ModuleBitcodeWriterBase::writePerModuleGlobalValueSummary() { auto *Summary = VI.getSummaryList()[0].get(); writePerModuleFunctionSummaryRecord( NameVals, Summary, VE.getValueID(&F), FSCallsRelBFAbbrev, - FSCallsProfileAbbrev, CallsiteAbbrev, AllocAbbrev, ContextIdAbbvId, F, - CallStackPos, CallStackCount); + FSCallsProfileAbbrev, CallsiteAbbrev, AllocAbbrev, ContextIdAbbvId, F); } // Capture references from GlobalVariable initializers, which are outside @@ -4786,20 +4692,13 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() { Abbv->Add(BitCodeAbbrevOp(bitc::FS_COMBINED_ALLOC_INFO)); Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // nummib Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 4)); // numver - // nummib x (alloc type, context radix tree index), + // nummib x (alloc type, numstackids, numstackids x stackidindex), // numver x version // optional: nummib x total size Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); unsigned AllocAbbrev = Stream.EmitAbbrev(std::move(Abbv)); - Abbv = std::make_shared<BitCodeAbbrev>(); - Abbv->Add(BitCodeAbbrevOp(bitc::FS_CONTEXT_RADIX_TREE_ARRAY)); - // n x entry - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Array)); - Abbv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 8)); - unsigned RadixAbbrev = Stream.EmitAbbrev(std::move(Abbv)); - auto shouldImportValueAsDecl = [&](GlobalValueSummary *GVS) -> bool { if (DecSummaries == nullptr) return false; @@ -4836,41 +4735,6 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() { NameVals.clear(); }; - // First walk through all the functions and collect the allocation contexts in - // their associated summaries, for use in constructing a radix tree of - // contexts. Note that we need to do this in the same order as the functions - // are processed further below since the call stack positions in the resulting - // radix tree array are identified based on this order. - MapVector<CallStackId, llvm::SmallVector<LinearFrameId>> CallStacks; - forEachSummary([&](GVInfo I, bool IsAliasee) { - GlobalValueSummary *S = I.second; - assert(S); - auto *FS = dyn_cast<FunctionSummary>(S); - if (!FS) - return; - collectMemProfCallStacks( - FS, - /*GetStackIndex*/ - [&](unsigned I) { - // Get the corresponding index into the list of StackIds actually - // being written for this combined index (which may be a subset in - // the case of distributed indexes). - assert(StackIdIndicesToIndex.contains(I)); - return StackIdIndicesToIndex[I]; - }, - CallStacks); - }); - // Finalize the radix tree, write it out, and get the map of positions in the - // linearized tree array. - DenseMap<CallStackId, LinearCallStackId> CallStackPos; - if (!CallStacks.empty()) { - CallStackPos = - writeMemoryProfileRadixTree(std::move(CallStacks), Stream, RadixAbbrev); - } - - // Keep track of the current index into the CallStackPos map. - CallStackId CallStackCount = 0; - DenseSet<GlobalValue::GUID> DefOrUseGUIDs; forEachSummary([&](GVInfo I, bool IsAliasee) { GlobalValueSummary *S = I.second; @@ -4949,7 +4813,7 @@ void IndexBitcodeWriter::writeCombinedGlobalValueSummary() { assert(StackIdIndicesToIndex.contains(I)); return StackIdIndicesToIndex[I]; }, - /*WriteContextSizeInfoIndex*/ false, CallStackPos, CallStackCount); + /*WriteContextSizeInfoIndex*/ false); NameVals.push_back(*ValueId); assert(ModuleIdMap.count(FS->modulePath())); |