diff --git a/llvm/include/llvm/MC/MCPseudoProbe.h b/llvm/include/llvm/MC/MCPseudoProbe.h --- a/llvm/include/llvm/MC/MCPseudoProbe.h +++ b/llvm/include/llvm/MC/MCPseudoProbe.h @@ -55,6 +55,7 @@ #include #include #include +#include #include namespace llvm { @@ -75,7 +76,7 @@ struct MCPseudoProbeFuncDesc { uint64_t FuncGUID = 0; uint64_t FuncHash = 0; - std::string FuncName; + StringRef FuncName; MCPseudoProbeFuncDesc(uint64_t GUID, uint64_t Hash, StringRef Name) : FuncGUID(GUID), FuncHash(Hash), FuncName(Name){}; @@ -351,7 +352,8 @@ public: // Decode pseudo_probe_desc section to build GUID to PseudoProbeFuncDesc map. - bool buildGUID2FuncDescMap(const uint8_t *Start, std::size_t Size); + bool buildGUID2FuncDescMap(const uint8_t *Start, std::size_t Size, + std::unordered_set &FuncNameStrings); // Decode pseudo_probe section to build address to probes map. bool buildAddress2ProbeMap(const uint8_t *Start, std::size_t Size); diff --git a/llvm/lib/MC/MCPseudoProbe.cpp b/llvm/lib/MC/MCPseudoProbe.cpp --- a/llvm/lib/MC/MCPseudoProbe.cpp +++ b/llvm/lib/MC/MCPseudoProbe.cpp @@ -312,8 +312,9 @@ return ErrorOr(Str); } -bool MCPseudoProbeDecoder::buildGUID2FuncDescMap(const uint8_t *Start, - std::size_t Size) { +bool MCPseudoProbeDecoder::buildGUID2FuncDescMap( + const uint8_t *Start, std::size_t Size, + std::unordered_set &FuncNameStrings) { // The pseudo_probe_desc section has a format like: // .section .pseudo_probe_desc,"",@progbits // .quad -5182264717993193164 // GUID @@ -350,8 +351,10 @@ uint64_t Hash = std::move(*ErrorOrHash); StringRef Name = std::move(*ErrorOrName); + auto It = FuncNameStrings.insert(Name.str()); // Initialize PseudoProbeFuncDesc and populate it into GUID2FuncDescMap - GUID2FuncDescMap.emplace(GUID, MCPseudoProbeFuncDesc(GUID, Hash, Name)); + GUID2FuncDescMap.emplace(GUID, + MCPseudoProbeFuncDesc(GUID, Hash, *It.first)); } assert(Data == End && "Have unprocessed data in pseudo_probe_desc section"); return true; diff --git a/llvm/tools/llvm-profgen/ProfiledBinary.h b/llvm/tools/llvm-profgen/ProfiledBinary.h --- a/llvm/tools/llvm-profgen/ProfiledBinary.h +++ b/llvm/tools/llvm-profgen/ProfiledBinary.h @@ -212,8 +212,12 @@ // if a given RVA is a valid code address. std::set> TextSections; + // Shared string table owning function name strings, keep only one table to + // save the memory. + std::unordered_set FuncNameStrings; + // A map of mapping function name to BinaryFunction info. - std::unordered_map BinaryFunctions; + StringMap BinaryFunctions; // An ordered map of mapping function's start offset to function range // relevant info. Currently to determine if the offset of ELF is the start of @@ -245,9 +249,6 @@ // The symbolizer used to get inline context for an instruction. std::unique_ptr Symbolizer; - // String table owning function name strings created from the symbolizer. - std::unordered_set NameStrings; - // A collection of functions to print disassembly for. StringSet<> DisassembleFunctionSet; @@ -437,8 +438,7 @@ return FRange->Func->Ranges; } - const std::unordered_map & - getAllBinaryFunctions() { + const StringMap &getAllBinaryFunctions() { return BinaryFunctions; } diff --git a/llvm/tools/llvm-profgen/ProfiledBinary.cpp b/llvm/tools/llvm-profgen/ProfiledBinary.cpp --- a/llvm/tools/llvm-profgen/ProfiledBinary.cpp +++ b/llvm/tools/llvm-profgen/ProfiledBinary.cpp @@ -175,7 +175,7 @@ NoFuncEntryNum++; if (ShowDetailedWarning) WithColor::warning() - << "Failed to determine function entry for " << F.first + << "Failed to determine function entry for " << F.first() << " due to inconsistent name from symbol table and dwarf info.\n"; } } @@ -336,7 +336,7 @@ StringRef Contents = unwrapOrError(Section.getContents(), FileName); if (!ProbeDecoder.buildGUID2FuncDescMap( reinterpret_cast(Contents.data()), - Contents.size())) + Contents.size(), FuncNameStrings)) exitWithError("Pseudo Probe decoder fail in .pseudo_probe_desc section"); } else if (SectionName == ".pseudo_probe") { StringRef Contents = unwrapOrError(Section.getContents(), FileName); @@ -630,10 +630,12 @@ // Different DWARF symbols can have same function name, search or create // BinaryFunction indexed by the name. - auto Ret = BinaryFunctions.emplace(Name, BinaryFunction()); + // Stablize in a shared function name string table. + auto It = FuncNameStrings.insert(Name); + auto Ret = BinaryFunctions.try_emplace(*It.first, BinaryFunction()); auto &Func = Ret.first->second; if (Ret.second) - Func.FuncName = Ret.first->first; + Func.FuncName = Ret.first->first(); for (const auto &Range : Ranges) { uint64_t FuncStart = Range.LowPC; @@ -714,7 +716,7 @@ } LineLocation Line(LineOffset, Discriminator); - auto It = NameStrings.insert(FunctionName.str()); + auto It = FuncNameStrings.insert(FunctionName.str()); CallStack.emplace_back(*It.first, Line); }