diff --git a/clang/docs/tools/clang-formatted-files.txt b/clang/docs/tools/clang-formatted-files.txt --- a/clang/docs/tools/clang-formatted-files.txt +++ b/clang/docs/tools/clang-formatted-files.txt @@ -5444,8 +5444,10 @@ llvm/include/llvm/ProfileData/GCOV.h llvm/include/llvm/ProfileData/InstrProfCorrelator.h llvm/include/llvm/ProfileData/InstrProfWriter.h +llvm/include/llvm/ProfileData/ItaniumManglingCanonicalizer.h llvm/include/llvm/ProfileData/ProfileCommon.h llvm/include/llvm/ProfileData/RawMemProfReader.h +llvm/include/llvm/ProfileData/SymbolRemappingReader.h llvm/include/llvm/ProfileData/Coverage/CoverageMappingReader.h llvm/include/llvm/ProfileData/Coverage/CoverageMappingWriter.h llvm/include/llvm/Remarks/BitstreamRemarkContainer.h @@ -5496,7 +5498,6 @@ llvm/include/llvm/Support/HashBuilder.h llvm/include/llvm/Support/InitLLVM.h llvm/include/llvm/Support/InstructionCost.h -llvm/include/llvm/Support/ItaniumManglingCanonicalizer.h llvm/include/llvm/Support/MD5.h llvm/include/llvm/Support/MemAlloc.h llvm/include/llvm/Support/MemoryBufferRef.h @@ -5518,7 +5519,6 @@ llvm/include/llvm/Support/SMTAPI.h llvm/include/llvm/Support/SourceMgr.h llvm/include/llvm/Support/SuffixTree.h -llvm/include/llvm/Support/SymbolRemappingReader.h llvm/include/llvm/Support/SystemUtils.h llvm/include/llvm/TargetParser/TargetParser.h llvm/include/llvm/Support/TrailingObjects.h @@ -7325,6 +7325,7 @@ llvm/unittests/Passes/TestPlugin.h llvm/unittests/ProfileData/InstrProfDataTest.cpp llvm/unittests/ProfileData/MemProfTest.cpp +llvm/unittests/ProfileData/SymbolRemappingReaderTest.cpp llvm/unittests/Remarks/BitstreamRemarksFormatTest.cpp llvm/unittests/Remarks/BitstreamRemarksParsingTest.cpp llvm/unittests/Remarks/RemarksLinkingTest.cpp @@ -7357,7 +7358,6 @@ llvm/unittests/Support/ScopedPrinterTest.cpp llvm/unittests/Support/SHA256.cpp llvm/unittests/Support/SuffixTreeTest.cpp -llvm/unittests/Support/SymbolRemappingReaderTest.cpp llvm/unittests/Support/TarWriterTest.cpp llvm/unittests/Support/ToolOutputFileTest.cpp llvm/unittests/Support/TypeTraitsTest.cpp diff --git a/llvm/include/llvm/ProfileData/SampleProfReader.h b/llvm/include/llvm/ProfileData/SampleProfReader.h --- a/llvm/include/llvm/ProfileData/SampleProfReader.h +++ b/llvm/include/llvm/ProfileData/SampleProfReader.h @@ -232,11 +232,11 @@ #include "llvm/IR/ProfileSummary.h" #include "llvm/ProfileData/GCOV.h" #include "llvm/ProfileData/SampleProf.h" +#include "llvm/ProfileData/SymbolRemappingReader.h" #include "llvm/Support/Debug.h" #include "llvm/Support/Discriminator.h" #include "llvm/Support/ErrorOr.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/SymbolRemappingReader.h" #include #include #include diff --git a/llvm/include/llvm/Support/ItaniumManglingCanonicalizer.h b/llvm/include/llvm/Support/ItaniumManglingCanonicalizer.h deleted file mode 100644 --- a/llvm/include/llvm/Support/ItaniumManglingCanonicalizer.h +++ /dev/null @@ -1,93 +0,0 @@ -//===--- ItaniumManglingCanonicalizer.h -------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines a class for computing equivalence classes of mangled names -// given a set of equivalences between name fragments. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_ITANIUMMANGLINGCANONICALIZER_H -#define LLVM_SUPPORT_ITANIUMMANGLINGCANONICALIZER_H - -#include - -namespace llvm { - -class StringRef; - -/// Canonicalizer for mangled names. -/// -/// This class allows specifying a list of "equivalent" manglings. For example, -/// you can specify that Ss is equivalent to -/// NSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE -/// and then manglings that refer to libstdc++'s 'std::string' will be -/// considered equivalent to manglings that are the same except that they refer -/// to libc++'s 'std::string'. -/// -/// This can be used when data (eg, profiling data) is available for a version -/// of a program built in a different configuration, with correspondingly -/// different manglings. -class ItaniumManglingCanonicalizer { -public: - ItaniumManglingCanonicalizer(); - ItaniumManglingCanonicalizer(const ItaniumManglingCanonicalizer &) = delete; - void operator=(const ItaniumManglingCanonicalizer &) = delete; - ~ItaniumManglingCanonicalizer(); - - enum class EquivalenceError { - Success, - - /// Both the equivalent manglings have already been used as components of - /// some other mangling we've looked at. It's too late to add this - /// equivalence. - ManglingAlreadyUsed, - - /// The first equivalent mangling is invalid. - InvalidFirstMangling, - - /// The second equivalent mangling is invalid. - InvalidSecondMangling, - }; - - enum class FragmentKind { - /// The mangling fragment is a (or a predefined ). - Name, - /// The mangling fragment is a . - Type, - /// The mangling fragment is an . - Encoding, - }; - - /// Add an equivalence between \p First and \p Second. Both manglings must - /// live at least as long as the canonicalizer. - EquivalenceError addEquivalence(FragmentKind Kind, StringRef First, - StringRef Second); - - using Key = uintptr_t; - - /// Form a canonical key for the specified mangling. They key will be the - /// same for all equivalent manglings, and different for any two - /// non-equivalent manglings, but is otherwise unspecified. - /// - /// Returns Key() if (and only if) the mangling is not a valid Itanium C++ - /// ABI mangling. - /// - /// The string denoted by Mangling must live as long as the canonicalizer. - Key canonicalize(StringRef Mangling); - - /// Find a canonical key for the specified mangling, if one has already been - /// formed. Otherwise returns Key(). - Key lookup(StringRef Mangling); - -private: - struct Impl; - Impl *P; -}; -} // namespace llvm - -#endif // LLVM_SUPPORT_ITANIUMMANGLINGCANONICALIZER_H diff --git a/llvm/include/llvm/Support/SymbolRemappingReader.h b/llvm/include/llvm/Support/SymbolRemappingReader.h deleted file mode 100644 --- a/llvm/include/llvm/Support/SymbolRemappingReader.h +++ /dev/null @@ -1,133 +0,0 @@ -//===- SymbolRemappingReader.h - Read symbol remapping file -----*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file contains definitions needed for reading and applying symbol -// remapping files. -// -// Support is provided only for the Itanium C++ name mangling scheme for now. -// -// NOTE: If you are making changes to this file format, please remember -// to document them in the Clang documentation at -// tools/clang/docs/UsersManual.rst. -// -// File format -// ----------- -// -// The symbol remappings are written as an ASCII text file. Blank lines and -// lines starting with a # are ignored. All other lines specify a kind of -// mangled name fragment, along with two fragments of that kind that should -// be treated as equivalent, separated by spaces. -// -// See http://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling for a -// description of the Itanium name mangling scheme. -// -// The accepted fragment kinds are: -// -// * name A , such as 6foobar or St3__1 -// * type A , such as Ss or N4llvm9StringRefE -// * encoding An (a complete mangling without the leading _Z) -// -// For example: -// -// # Ignore int / long differences to treat symbols from 32-bit and 64-bit -// # builds with differing size_t / ptrdiff_t / intptr_t as equivalent. -// type i l -// type j m -// -// # Ignore differences between libc++ and libstdc++, and between libstdc++'s -// # C++98 and C++11 ABIs. -// name 3std St3__1 -// name 3std St7__cxx11 -// -// # Remap a function overload to a specialization of a template (including -// # any local symbols declared within it). -// encoding N2NS1fEi N2NS1fIiEEvT_ -// -// # Substitutions must be remapped separately from namespace 'std' for now. -// name Sa NSt3__19allocatorE -// name Sb NSt3__112basic_stringE -// type Ss NSt3__112basic_stringIcSt11char_traitsIcESaE -// # ... -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_SUPPORT_SYMBOLREMAPPINGREADER_H -#define LLVM_SUPPORT_SYMBOLREMAPPINGREADER_H - -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/ItaniumManglingCanonicalizer.h" - -namespace llvm { - -class MemoryBuffer; - -class SymbolRemappingParseError : public ErrorInfo { -public: - SymbolRemappingParseError(StringRef File, int64_t Line, const Twine &Message) - : File(File), Line(Line), Message(Message.str()) {} - - void log(llvm::raw_ostream &OS) const override { - OS << File << ':' << Line << ": " << Message; - } - std::error_code convertToErrorCode() const override { - return llvm::inconvertibleErrorCode(); - } - - StringRef getFileName() const { return File; } - int64_t getLineNum() const { return Line; } - StringRef getMessage() const { return Message; } - - static char ID; - -private: - std::string File; - int64_t Line; - std::string Message; -}; - -/// Reader for symbol remapping files. -/// -/// Remaps the symbol names in profile data to match those in the program -/// according to a set of rules specified in a given file. -class SymbolRemappingReader { -public: - /// Read remappings from the given buffer, which must live as long as - /// the remapper. - Error read(MemoryBuffer &B); - - /// A Key represents an equivalence class of symbol names. - using Key = uintptr_t; - - /// Construct a key for the given symbol, or return an existing one if an - /// equivalent name has already been inserted. The symbol name must live - /// as long as the remapper. - /// - /// The result will be Key() if the name cannot be remapped (typically - /// because it is not a valid mangled name). - Key insert(StringRef FunctionName) { - return Canonicalizer.canonicalize(FunctionName); - } - - /// Map the given symbol name into the key for the corresponding equivalence - /// class. - /// - /// The result will typically be Key() if no equivalent symbol has been - /// inserted, but this is not guaranteed: a Key different from all keys ever - /// returned by \c insert may be returned instead. - Key lookup(StringRef FunctionName) { - return Canonicalizer.lookup(FunctionName); - } - -private: - ItaniumManglingCanonicalizer Canonicalizer; -}; - -} // end namespace llvm - -#endif // LLVM_SUPPORT_SYMBOLREMAPPINGREADER_H diff --git a/llvm/lib/ProfileData/CMakeLists.txt b/llvm/lib/ProfileData/CMakeLists.txt --- a/llvm/lib/ProfileData/CMakeLists.txt +++ b/llvm/lib/ProfileData/CMakeLists.txt @@ -4,12 +4,14 @@ InstrProfCorrelator.cpp InstrProfReader.cpp InstrProfWriter.cpp + ItaniumManglingCanonicalizer.cpp MemProf.cpp ProfileSummaryBuilder.cpp + RawMemProfReader.cpp SampleProf.cpp SampleProfReader.cpp SampleProfWriter.cpp - RawMemProfReader.cpp + SymbolRemappingReader.cpp ADDITIONAL_HEADER_DIRS ${LLVM_MAIN_INCLUDE_DIR}/llvm/ProfileData diff --git a/llvm/lib/ProfileData/InstrProfReader.cpp b/llvm/lib/ProfileData/InstrProfReader.cpp --- a/llvm/lib/ProfileData/InstrProfReader.cpp +++ b/llvm/lib/ProfileData/InstrProfReader.cpp @@ -20,12 +20,12 @@ #include "llvm/ProfileData/InstrProf.h" #include "llvm/ProfileData/MemProf.h" #include "llvm/ProfileData/ProfileCommon.h" +#include "llvm/ProfileData/SymbolRemappingReader.h" #include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include "llvm/Support/ErrorOr.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/SwapByteOrder.h" -#include "llvm/Support/SymbolRemappingReader.h" #include "llvm/Support/VirtualFileSystem.h" #include #include diff --git a/llvm/lib/Support/CMakeLists.txt b/llvm/lib/Support/CMakeLists.txt --- a/llvm/lib/Support/CMakeLists.txt +++ b/llvm/lib/Support/CMakeLists.txt @@ -175,7 +175,6 @@ InstructionCost.cpp IntEqClasses.cpp IntervalMap.cpp - ItaniumManglingCanonicalizer.cpp JSON.cpp KnownBits.cpp LEB128.cpp @@ -218,7 +217,6 @@ StringSaver.cpp StringRef.cpp SuffixTree.cpp - SymbolRemappingReader.cpp SystemUtils.cpp TarWriter.cpp ThreadPool.cpp diff --git a/llvm/lib/Support/ItaniumManglingCanonicalizer.cpp b/llvm/lib/Support/ItaniumManglingCanonicalizer.cpp deleted file mode 100644 --- a/llvm/lib/Support/ItaniumManglingCanonicalizer.cpp +++ /dev/null @@ -1,307 +0,0 @@ -//===----------------- ItaniumManglingCanonicalizer.cpp -------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "llvm/Support/ItaniumManglingCanonicalizer.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/FoldingSet.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Demangle/ItaniumDemangle.h" -#include "llvm/Support/Allocator.h" - -using namespace llvm; -using llvm::itanium_demangle::ForwardTemplateReference; -using llvm::itanium_demangle::Node; -using llvm::itanium_demangle::NodeKind; -using llvm::itanium_demangle::StringView; - -namespace { -struct FoldingSetNodeIDBuilder { - llvm::FoldingSetNodeID &ID; - void operator()(const Node *P) { ID.AddPointer(P); } - void operator()(StringView Str) { - ID.AddString(llvm::StringRef(Str.begin(), Str.size())); - } - template - std::enable_if_t || std::is_enum_v> operator()(T V) { - ID.AddInteger((unsigned long long)V); - } - void operator()(itanium_demangle::NodeArray A) { - ID.AddInteger(A.size()); - for (const Node *N : A) - (*this)(N); - } -}; - -template -void profileCtor(llvm::FoldingSetNodeID &ID, Node::Kind K, T ...V) { - FoldingSetNodeIDBuilder Builder = {ID}; - Builder(K); - int VisitInOrder[] = { - (Builder(V), 0) ..., - 0 // Avoid empty array if there are no arguments. - }; - (void)VisitInOrder; -} - -// FIXME: Convert this to a generic lambda when possible. -template struct ProfileSpecificNode { - FoldingSetNodeID &ID; - template void operator()(T ...V) { - profileCtor(ID, NodeKind::Kind, V...); - } -}; - -struct ProfileNode { - FoldingSetNodeID &ID; - template void operator()(const NodeT *N) { - N->match(ProfileSpecificNode{ID}); - } -}; - -template<> void ProfileNode::operator()(const ForwardTemplateReference *N) { - llvm_unreachable("should never canonicalize a ForwardTemplateReference"); -} - -void profileNode(llvm::FoldingSetNodeID &ID, const Node *N) { - N->visit(ProfileNode{ID}); -} - -class FoldingNodeAllocator { - class alignas(alignof(Node *)) NodeHeader : public llvm::FoldingSetNode { - public: - // 'Node' in this context names the injected-class-name of the base class. - itanium_demangle::Node *getNode() { - return reinterpret_cast(this + 1); - } - void Profile(llvm::FoldingSetNodeID &ID) { profileNode(ID, getNode()); } - }; - - BumpPtrAllocator RawAlloc; - llvm::FoldingSet Nodes; - -public: - void reset() {} - - template - std::pair getOrCreateNode(bool CreateNewNodes, Args &&... As) { - // FIXME: Don't canonicalize forward template references for now, because - // they contain state (the resolved template node) that's not known at their - // point of creation. - if (std::is_same::value) { - // Note that we don't use if-constexpr here and so we must still write - // this code in a generic form. - return {new (RawAlloc.Allocate(sizeof(T), alignof(T))) - T(std::forward(As)...), - true}; - } - - llvm::FoldingSetNodeID ID; - profileCtor(ID, NodeKind::Kind, As...); - - void *InsertPos; - if (NodeHeader *Existing = Nodes.FindNodeOrInsertPos(ID, InsertPos)) - return {static_cast(Existing->getNode()), false}; - - if (!CreateNewNodes) - return {nullptr, true}; - - static_assert(alignof(T) <= alignof(NodeHeader), - "underaligned node header for specific node kind"); - void *Storage = - RawAlloc.Allocate(sizeof(NodeHeader) + sizeof(T), alignof(NodeHeader)); - NodeHeader *New = new (Storage) NodeHeader; - T *Result = new (New->getNode()) T(std::forward(As)...); - Nodes.InsertNode(New, InsertPos); - return {Result, true}; - } - - template - Node *makeNode(Args &&...As) { - return getOrCreateNode(true, std::forward(As)...).first; - } - - void *allocateNodeArray(size_t sz) { - return RawAlloc.Allocate(sizeof(Node *) * sz, alignof(Node *)); - } -}; - -class CanonicalizerAllocator : public FoldingNodeAllocator { - Node *MostRecentlyCreated = nullptr; - Node *TrackedNode = nullptr; - bool TrackedNodeIsUsed = false; - bool CreateNewNodes = true; - llvm::SmallDenseMap Remappings; - - template Node *makeNodeSimple(Args &&...As) { - std::pair Result = - getOrCreateNode(CreateNewNodes, std::forward(As)...); - if (Result.second) { - // Node is new. Make a note of that. - MostRecentlyCreated = Result.first; - } else if (Result.first) { - // Node is pre-existing; check if it's in our remapping table. - if (auto *N = Remappings.lookup(Result.first)) { - Result.first = N; - assert(Remappings.find(Result.first) == Remappings.end() && - "should never need multiple remap steps"); - } - if (Result.first == TrackedNode) - TrackedNodeIsUsed = true; - } - return Result.first; - } - - /// Helper to allow makeNode to be partially-specialized on T. - template struct MakeNodeImpl { - CanonicalizerAllocator &Self; - template Node *make(Args &&...As) { - return Self.makeNodeSimple(std::forward(As)...); - } - }; - -public: - template Node *makeNode(Args &&...As) { - return MakeNodeImpl{*this}.make(std::forward(As)...); - } - - void reset() { MostRecentlyCreated = nullptr; } - - void setCreateNewNodes(bool CNN) { CreateNewNodes = CNN; } - - void addRemapping(Node *A, Node *B) { - // Note, we don't need to check whether B is also remapped, because if it - // was we would have already remapped it when building it. - Remappings.insert(std::make_pair(A, B)); - } - - bool isMostRecentlyCreated(Node *N) const { return MostRecentlyCreated == N; } - - void trackUsesOf(Node *N) { - TrackedNode = N; - TrackedNodeIsUsed = false; - } - bool trackedNodeIsUsed() const { return TrackedNodeIsUsed; } -}; - -// FIXME: Also expand built-in substitutions? - -using CanonicalizingDemangler = - itanium_demangle::ManglingParser; -} // namespace - -struct ItaniumManglingCanonicalizer::Impl { - CanonicalizingDemangler Demangler = {nullptr, nullptr}; -}; - -ItaniumManglingCanonicalizer::ItaniumManglingCanonicalizer() : P(new Impl) {} -ItaniumManglingCanonicalizer::~ItaniumManglingCanonicalizer() { delete P; } - -ItaniumManglingCanonicalizer::EquivalenceError -ItaniumManglingCanonicalizer::addEquivalence(FragmentKind Kind, StringRef First, - StringRef Second) { - auto &Alloc = P->Demangler.ASTAllocator; - Alloc.setCreateNewNodes(true); - - auto Parse = [&](StringRef Str) { - P->Demangler.reset(Str.begin(), Str.end()); - Node *N = nullptr; - switch (Kind) { - // A , with minor extensions to allow arbitrary namespace and - // template names that can't easily be written as s. - case FragmentKind::Name: - // Very special case: allow "St" as a shorthand for "3std". It's not - // valid as a mangling, but is nonetheless the most natural - // way to name the 'std' namespace. - if (Str.size() == 2 && P->Demangler.consumeIf("St")) - N = P->Demangler.make("std"); - // We permit substitutions to name templates without their template - // arguments. This mostly just falls out, as almost all template names - // are valid as s, but we also want to parse s as - // s, even though they're not. - else if (Str.startswith("S")) - // Parse the substitution and optional following template arguments. - N = P->Demangler.parseType(); - else - N = P->Demangler.parseName(); - break; - - // A . - case FragmentKind::Type: - N = P->Demangler.parseType(); - break; - - // An . - case FragmentKind::Encoding: - N = P->Demangler.parseEncoding(); - break; - } - - // If we have trailing junk, the mangling is invalid. - if (P->Demangler.numLeft() != 0) - N = nullptr; - - // If any node was created after N, then we cannot safely remap it because - // it might already be in use by another node. - return std::make_pair(N, Alloc.isMostRecentlyCreated(N)); - }; - - Node *FirstNode, *SecondNode; - bool FirstIsNew, SecondIsNew; - - std::tie(FirstNode, FirstIsNew) = Parse(First); - if (!FirstNode) - return EquivalenceError::InvalidFirstMangling; - - Alloc.trackUsesOf(FirstNode); - std::tie(SecondNode, SecondIsNew) = Parse(Second); - if (!SecondNode) - return EquivalenceError::InvalidSecondMangling; - - // If they're already equivalent, there's nothing to do. - if (FirstNode == SecondNode) - return EquivalenceError::Success; - - if (FirstIsNew && !Alloc.trackedNodeIsUsed()) - Alloc.addRemapping(FirstNode, SecondNode); - else if (SecondIsNew) - Alloc.addRemapping(SecondNode, FirstNode); - else - return EquivalenceError::ManglingAlreadyUsed; - - return EquivalenceError::Success; -} - -static ItaniumManglingCanonicalizer::Key -parseMaybeMangledName(CanonicalizingDemangler &Demangler, StringRef Mangling, - bool CreateNewNodes) { - Demangler.ASTAllocator.setCreateNewNodes(CreateNewNodes); - Demangler.reset(Mangling.begin(), Mangling.end()); - // Attempt demangling only for names that look like C++ mangled names. - // Otherwise, treat them as extern "C" names. We permit the latter to - // be remapped by (eg) - // encoding 6memcpy 7memmove - // consistent with how they are encoded as local-names inside a C++ mangling. - Node *N; - if (Mangling.startswith("_Z") || Mangling.startswith("__Z") || - Mangling.startswith("___Z") || Mangling.startswith("____Z")) - N = Demangler.parse(); - else - N = Demangler.make( - StringView(Mangling.data(), Mangling.size())); - return reinterpret_cast(N); -} - -ItaniumManglingCanonicalizer::Key -ItaniumManglingCanonicalizer::canonicalize(StringRef Mangling) { - return parseMaybeMangledName(P->Demangler, Mangling, true); -} - -ItaniumManglingCanonicalizer::Key -ItaniumManglingCanonicalizer::lookup(StringRef Mangling) { - return parseMaybeMangledName(P->Demangler, Mangling, false); -} diff --git a/llvm/lib/Support/SymbolRemappingReader.cpp b/llvm/lib/Support/SymbolRemappingReader.cpp deleted file mode 100644 --- a/llvm/lib/Support/SymbolRemappingReader.cpp +++ /dev/null @@ -1,81 +0,0 @@ -//===- SymbolRemappingReader.cpp - Read symbol remapping file -------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file contains definitions needed for reading and applying symbol -// remapping files. -// -//===----------------------------------------------------------------------===// - -#include "llvm/Support/SymbolRemappingReader.h" -#include "llvm/ADT/StringSwitch.h" -#include "llvm/ADT/Twine.h" -#include "llvm/Support/LineIterator.h" -#include "llvm/Support/MemoryBuffer.h" - -using namespace llvm; - -char SymbolRemappingParseError::ID; - -/// Load a set of name remappings from a text file. -/// -/// See the documentation at the top of the file for an explanation of -/// the expected format. -Error SymbolRemappingReader::read(MemoryBuffer &B) { - line_iterator LineIt(B, /*SkipBlanks=*/true, '#'); - - auto ReportError = [&](Twine Msg) { - return llvm::make_error( - B.getBufferIdentifier(), LineIt.line_number(), Msg); - }; - - for (; !LineIt.is_at_eof(); ++LineIt) { - StringRef Line = *LineIt; - Line = Line.ltrim(' '); - // line_iterator only detects comments starting in column 1. - if (Line.startswith("#") || Line.empty()) - continue; - - SmallVector Parts; - Line.split(Parts, ' ', /*MaxSplits*/-1, /*KeepEmpty*/false); - - if (Parts.size() != 3) - return ReportError("Expected 'kind mangled_name mangled_name', " - "found '" + Line + "'"); - - using FK = ItaniumManglingCanonicalizer::FragmentKind; - std::optional FragmentKind = StringSwitch>(Parts[0]) - .Case("name", FK::Name) - .Case("type", FK::Type) - .Case("encoding", FK::Encoding) - .Default(std::nullopt); - if (!FragmentKind) - return ReportError("Invalid kind, expected 'name', 'type', or 'encoding'," - " found '" + Parts[0] + "'"); - - using EE = ItaniumManglingCanonicalizer::EquivalenceError; - switch (Canonicalizer.addEquivalence(*FragmentKind, Parts[1], Parts[2])) { - case EE::Success: - break; - - case EE::ManglingAlreadyUsed: - return ReportError("Manglings '" + Parts[1] + "' and '" + Parts[2] + "' " - "have both been used in prior remappings. Move this " - "remapping earlier in the file."); - - case EE::InvalidFirstMangling: - return ReportError("Could not demangle '" + Parts[1] + "' " - "as a <" + Parts[0] + ">; invalid mangling?"); - - case EE::InvalidSecondMangling: - return ReportError("Could not demangle '" + Parts[2] + "' " - "as a <" + Parts[0] + ">; invalid mangling?"); - } - } - - return Error::success(); -} diff --git a/llvm/tools/llvm-cxxmap/CMakeLists.txt b/llvm/tools/llvm-cxxmap/CMakeLists.txt --- a/llvm/tools/llvm-cxxmap/CMakeLists.txt +++ b/llvm/tools/llvm-cxxmap/CMakeLists.txt @@ -1,5 +1,6 @@ set(LLVM_LINK_COMPONENTS Core + ProfileData Support ) diff --git a/llvm/tools/llvm-cxxmap/llvm-cxxmap.cpp b/llvm/tools/llvm-cxxmap/llvm-cxxmap.cpp --- a/llvm/tools/llvm-cxxmap/llvm-cxxmap.cpp +++ b/llvm/tools/llvm-cxxmap/llvm-cxxmap.cpp @@ -14,12 +14,12 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ProfileData/SymbolRemappingReader.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/InitLLVM.h" #include "llvm/Support/LineIterator.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/SymbolRemappingReader.h" #include "llvm/Support/WithColor.h" #include "llvm/Support/raw_ostream.h" diff --git a/llvm/unittests/ProfileData/CMakeLists.txt b/llvm/unittests/ProfileData/CMakeLists.txt --- a/llvm/unittests/ProfileData/CMakeLists.txt +++ b/llvm/unittests/ProfileData/CMakeLists.txt @@ -10,8 +10,10 @@ CoverageMappingTest.cpp InstrProfDataTest.cpp InstrProfTest.cpp - SampleProfTest.cpp + ItaniumManglingCanonicalizerTest.cpp MemProfTest.cpp + SampleProfTest.cpp + SymbolRemappingReaderTest.cpp ) target_link_libraries(ProfileDataTests PRIVATE LLVMTestingSupport) diff --git a/llvm/unittests/Support/CMakeLists.txt b/llvm/unittests/Support/CMakeLists.txt --- a/llvm/unittests/Support/CMakeLists.txt +++ b/llvm/unittests/Support/CMakeLists.txt @@ -46,7 +46,6 @@ HashBuilderTest.cpp IndexedAccessorTest.cpp InstructionCostTest.cpp - ItaniumManglingCanonicalizerTest.cpp JSONTest.cpp KnownBitsTest.cpp LEB128Test.cpp @@ -76,7 +75,6 @@ SpecialCaseListTest.cpp SuffixTreeTest.cpp SwapByteOrderTest.cpp - SymbolRemappingReaderTest.cpp TarWriterTest.cpp TaskQueueTest.cpp ThreadPool.cpp diff --git a/llvm/unittests/Support/ItaniumManglingCanonicalizerTest.cpp b/llvm/unittests/Support/ItaniumManglingCanonicalizerTest.cpp deleted file mode 100644 --- a/llvm/unittests/Support/ItaniumManglingCanonicalizerTest.cpp +++ /dev/null @@ -1,389 +0,0 @@ -//===-------------- ItaniumManglingCanonicalizerTest.cpp ------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "llvm/Support/ItaniumManglingCanonicalizer.h" -#include "llvm/ADT/ArrayRef.h" -#include "llvm/ADT/StringRef.h" -#include "gtest/gtest.h" - -#include -#include -#include - -using namespace llvm; - -namespace { - -using EquivalenceError = llvm::ItaniumManglingCanonicalizer::EquivalenceError; -using FragmentKind = llvm::ItaniumManglingCanonicalizer::FragmentKind; - -struct Equivalence { - FragmentKind Kind; - llvm::StringRef First; - llvm::StringRef Second; -}; - -// A set of manglings that should all be considered equivalent. -using EquivalenceClass = std::vector; - -struct Testcase { - // A set of equivalences to register. - std::vector Equivalences; - // A set of distinct equivalence classes created by registering the - // equivalences. - std::vector Classes; -}; - -// A function that returns a set of test cases. -static std::vector getTestcases() { - return { - // Three different manglings for std::string (old libstdc++, new libstdc++, - // libc++). - { - { - {FragmentKind::Type, "Ss", - "NSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE"}, - {FragmentKind::Type, "Ss", - "NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE"}, - }, - { - {"_Z1fv"}, - {"_Z1fSs", - "_Z1fNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE", - "_Z1fNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE"}, - {"_ZNKSs4sizeEv", - "_ZNKSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE4sizeEv", - "_ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE4sizeEv"}, - } - }, - - // Check that substitutions are properly handled. - { - { - // ::X <-> ::N::X - {FragmentKind::Type, "1X", "N1N1XIiEE"}, - // ::T, T> <-> T - {FragmentKind::Type, "1TIS_IiiES0_E", "1TIiE"}, - // A::B::foo <-> AB::foo - {FragmentKind::Name, "N1A1B3fooE", "N2AB3fooE"}, - }, - { - {"_Z1f1XPS_RS_", "_Z1fN1N1XIiEEPS1_RS1_"}, - {"_ZN1A1B3fooE1TIS1_IiiES2_EPS3_RS3_", "_ZN2AB3fooE1TIiEPS1_RS1_"}, - } - }, - - // Check that nested equivalences are properly handled. - { - { - // std::__1::char_traits == std::__cxx11::char_traits - // (Note that this is unused and should make no difference, - // but it should not cause us to fail to match up the cases - // below.) - {FragmentKind::Name, - "NSt3__111char_traitsE", - "NSt7__cxx1111char_traitsE"}, - // std::__1::allocator == std::allocator - {FragmentKind::Name, - "NSt3__19allocatorE", - "Sa"}, // "Sa" is not strictly a but we accept it as one. - // std::__1::vector == std::vector - {FragmentKind::Name, - "St6vector", - "NSt3__16vectorE"}, - // std::__1::basic_string< - // char - // std::__1::char_traits, - // std::__1::allocator> == - // std::__cxx11::basic_string< - // char, - // std::char_traits, - // std::allocator> - {FragmentKind::Type, - "NSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE", - "NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE"}, - // X <-> X - {FragmentKind::Type, "1XI1AE", "1XI1BE"}, - // X <-> Y - {FragmentKind::Name, "1X", "1Y"}, - }, - { - // f(std::string) - {"_Z1fNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE", - "_Z1fNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE"}, - // f(std::vector) - {"_Z1fSt6vectorIiSaIiEE", "_Z1fNSt3__16vectorIiNS_9allocatorIiEEEE"}, - // f(X), f(X), f(Y), f(Y) - {"_Z1f1XI1AE", "_Z1f1XI1BE", "_Z1f1YI1AE", "_Z1f1YI1BE"}, - // f(X), f(Y) - {"_Z1f1XI1CE", "_Z1f1YI1CE"}, - } - }, - - // Check namespace equivalences. - { - { - // std::__1 == std::__cxx11 - {FragmentKind::Name, "St3__1", "St7__cxx11"}, - // std::__1::allocator == std::allocator - {FragmentKind::Name, "NSt3__19allocatorE", "Sa"}, - // std::vector == std::__1::vector - {FragmentKind::Name, "St6vector", "NSt3__16vectorE"}, - // std::__cxx11::char_traits == std::char_traits - // (This indirectly means that std::__1::char_traits == std::char_traits, - // due to the std::__cxx11 == std::__1 equivalence, which is what we rely - // on below.) - {FragmentKind::Name, "NSt7__cxx1111char_traitsE", "St11char_traits"}, - }, - { - // f(std::foo) - {"_Z1fNSt7__cxx113fooE", - "_Z1fNSt3__13fooE"}, - // f(std::string) - {"_Z1fNSt7__cxx1111char_traitsIcEE", - "_Z1fNSt3__111char_traitsIcEE", - "_Z1fSt11char_traitsIcE"}, - // f(std::string) - {"_Z1fNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE", - "_Z1fNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE"}, - // f(std::vector) - {"_Z1fSt6vectorIiSaIiEE", "_Z1fNSt3__16vectorIiNS_9allocatorIiEEEE"}, - } - }, - - // Check namespace equivalences for namespace 'std'. We support using 'St' - // for this, despite it not technically being a . - { - { - // std::__1 == std - {FragmentKind::Name, "St3__1", "St"}, - // std::__1 == std::__cxx11 - {FragmentKind::Name, "St3__1", "St7__cxx11"}, - // FIXME: Should a 'std' equivalence also cover the predefined - // substitutions? - // std::__1::allocator == std::allocator - {FragmentKind::Name, "NSt3__19allocatorE", "Sa"}, - }, - { - {"_Z1fSt3foo", "_Z1fNSt3__13fooE", "_Z1fNSt7__cxx113fooE"}, - {"_Z1fNSt3bar3bazE", "_Z1fNSt3__13bar3bazE"}, - // f(std::string) - {"_Z1fNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEE", - "_Z1fNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE"}, - // f(std::vector) - {"_Z1fSt6vectorIiSaIiEE", "_Z1fNSt3__16vectorIiNS_9allocatorIiEEEE"}, - } - }, - - // Check mutually-recursive equivalences. - { - { - {FragmentKind::Type, "1A", "1B"}, - {FragmentKind::Type, "1A", "1C"}, - {FragmentKind::Type, "1D", "1B"}, - {FragmentKind::Type, "1C", "1E"}, - }, - { - {"_Z1f1A", "_Z1f1B", "_Z1f1C", "_Z1f1D", "_Z1f1E"}, - {"_Z1f1F"}, - } - }, - - // Check s. - { - { - {FragmentKind::Encoding, "1fv", "1gv"}, - }, - { - // f(void) -> g(void) - {"_Z1fv", "_Z1gv"}, - // static local 'n' in f(void) -> static local 'n' in g(void) - {"_ZZ1fvE1n", "_ZZ1gvE1n"}, - } - }, - - // Corner case: the substitution can appear within its own expansion. - { - { - // X <-> Y - {FragmentKind::Type, "1X", "1YI1XE"}, - // A <-> B - {FragmentKind::Type, "1AI1BE", "1B"}, - }, - { - // f(X) == f(Y) == f(Y>) == f(Y>>) - {"_Z1f1X", "_Z1f1YI1XE", "_Z1f1YIS_I1XEE", "_Z1f1YIS_IS_I1XEEE"}, - // f(B) == f(A) == f(A>) == f(A>>) - {"_Z1f1B", "_Z1f1AI1BE", "_Z1f1AIS_I1BEE", "_Z1f1AIS_IS_I1BEEE"}, - } - }, - - // Redundant equivalences are accepted (and have no effect). - { - { - {FragmentKind::Name, "3std", "St"}, - {FragmentKind::Name, "1X", "1Y"}, - {FragmentKind::Name, "N1X1ZE", "N1Y1ZE"}, - }, - {} - }, - - // Check that ctor and dtor variants are considered distinct. - { - {}, - {{"_ZN1XC1Ev"}, {"_ZN1XC2Ev"}, {"_ZN1XD1Ev"}, {"_ZN1XD2Ev"}} - }, - - // Ensure array types with and without bounds are handled properly. - { - { - {FragmentKind::Type, "A_i", "A1_f"}, - }, - { - {"_Z1fRA_i", "_Z1fRA_i", "_Z1fRA1_f"}, - {"_Z1fRA1_i"}, {"_Z1fRA_f"}, - } - }, - - // Unmangled names can be remapped as complete encodings. - { - { - {FragmentKind::Encoding, "3foo", "3bar"}, - }, - { - // foo == bar - {"foo", "bar"}, - // void f() == void f() - {"_Z1fIL_Z3fooEEvv", "_Z1fIL_Z3barEEvv"}, - } - }, - }; -} - -// A function to get a set of test cases for forward template references. -static std::vector getForwardTemplateReferenceTestcases() { - return { - // ForwardTemplateReference does not support canonicalization. - // FIXME: We should consider ways of fixing this, perhaps by eliminating - // the ForwardTemplateReference node with a tree transformation. - { - { - // X::operator T() == Y::operator T() - {FragmentKind::Encoding, "N1XcvT_I1AEEv", "N1YcvT_I1AEEv"}, - // A == B - {FragmentKind::Name, "1A", "1B"}, - }, - { - // All combinations result in unique equivalence classes. - {"_ZN1XcvT_I1AEEv"}, - {"_ZN1XcvT_I1BEEv"}, - {"_ZN1YcvT_I1AEEv"}, - {"_ZN1YcvT_I1BEEv"}, - // Even giving the same string twice gives a new class. - {"_ZN1XcvT_I1AEEv"}, - } - }, - }; -} - -template -static void testTestcases(ArrayRef Testcases) { - for (const auto &Testcase : Testcases) { - llvm::ItaniumManglingCanonicalizer Canonicalizer; - for (const auto &Equiv : Testcase.Equivalences) { - auto Result = - Canonicalizer.addEquivalence(Equiv.Kind, Equiv.First, Equiv.Second); - EXPECT_EQ(Result, EquivalenceError::Success) - << "couldn't add equivalence between " << Equiv.First << " and " - << Equiv.Second; - } - - using CanonKey = llvm::ItaniumManglingCanonicalizer::Key; - - std::map Keys; - if (CanonicalizeFirst) - for (const auto &Class : Testcase.Classes) - Keys.insert({&Class, Canonicalizer.canonicalize(*Class.begin())}); - - std::map Found; - for (const auto &Class : Testcase.Classes) { - CanonKey ClassKey = Keys[&Class]; - for (llvm::StringRef Str : Class) { - // Force a copy to be made when calling lookup to test that it doesn't - // retain any part of the provided string. - CanonKey ThisKey = CanonicalizeFirst - ? Canonicalizer.lookup(std::string(Str)) - : Canonicalizer.canonicalize(Str); - EXPECT_NE(ThisKey, CanonKey()) << "couldn't canonicalize " << Str; - if (ClassKey) { - EXPECT_EQ(ThisKey, ClassKey) - << Str << " not in the same class as " << *Class.begin(); - } else { - ClassKey = ThisKey; - } - } - EXPECT_TRUE(Found.insert({ClassKey, *Class.begin()}).second) - << *Class.begin() << " is in the same class as " << Found[ClassKey]; - } - } -} - -TEST(ItaniumManglingCanonicalizerTest, TestCanonicalize) { - testTestcases(getTestcases()); -} - -TEST(ItaniumManglingCanonicalizerTest, TestLookup) { - testTestcases(getTestcases()); -} - -TEST(ItaniumManglingCanonicalizerTest, TestForwardTemplateReference) { - // lookup(...) after canonicalization (intentionally) returns different - // values for this testcase. - testTestcases(getForwardTemplateReferenceTestcases()); -} - - -TEST(ItaniumManglingCanonicalizerTest, TestInvalidManglings) { - llvm::ItaniumManglingCanonicalizer Canonicalizer; - EXPECT_EQ(Canonicalizer.addEquivalence(FragmentKind::Type, "", "1X"), - EquivalenceError::InvalidFirstMangling); - EXPECT_EQ(Canonicalizer.addEquivalence(FragmentKind::Type, "1X", "1ab"), - EquivalenceError::InvalidSecondMangling); - EXPECT_EQ(Canonicalizer.canonicalize("_Z3fooE"), - llvm::ItaniumManglingCanonicalizer::Key()); - EXPECT_EQ(Canonicalizer.canonicalize("_Zfoo"), - llvm::ItaniumManglingCanonicalizer::Key()); - - // A reference to a template parameter ('T_' etc) cannot appear in a , - // because we don't have template arguments to bind to it. (The arguments in - // an 'I ... E' construct in the aren't registered as - // backreferenceable arguments in this sense, because they're not part of - // the template argument list of an . - EXPECT_EQ(Canonicalizer.addEquivalence(FragmentKind::Name, "N1XcvT_I1AEE", - "1f"), - EquivalenceError::InvalidFirstMangling); -} - -TEST(ItaniumManglingCanonicalizerTest, TestBadEquivalenceOrder) { - llvm::ItaniumManglingCanonicalizer Canonicalizer; - EXPECT_EQ(Canonicalizer.addEquivalence(FragmentKind::Type, "N1P1XE", "N1Q1XE"), - EquivalenceError::Success); - EXPECT_EQ(Canonicalizer.addEquivalence(FragmentKind::Type, "1P", "1Q"), - EquivalenceError::ManglingAlreadyUsed); - - EXPECT_EQ(Canonicalizer.addEquivalence(FragmentKind::Type, "N1C1XE", "N1A1YE"), - EquivalenceError::Success); - EXPECT_EQ(Canonicalizer.addEquivalence(FragmentKind::Type, "1A", "1B"), - EquivalenceError::Success); - EXPECT_EQ(Canonicalizer.addEquivalence(FragmentKind::Type, "1C", "1D"), - EquivalenceError::Success); - EXPECT_EQ(Canonicalizer.addEquivalence(FragmentKind::Type, "1B", "1D"), - EquivalenceError::ManglingAlreadyUsed); -} - -} // end anonymous namespace diff --git a/llvm/unittests/Support/SymbolRemappingReaderTest.cpp b/llvm/unittests/Support/SymbolRemappingReaderTest.cpp deleted file mode 100644 --- a/llvm/unittests/Support/SymbolRemappingReaderTest.cpp +++ /dev/null @@ -1,95 +0,0 @@ -//===- unittests/Support/SymbolRemappingReaderTest.cpp --------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "llvm/Support/SymbolRemappingReader.h" -#include "llvm/Support/MemoryBuffer.h" -#include "gtest/gtest.h" - -using namespace llvm; - -namespace { -class SymbolRemappingReaderTest : public testing::Test { -public: - std::unique_ptr Buffer; - SymbolRemappingReader Reader; - - std::string readWithErrors(StringRef Text, StringRef BufferName) { - Buffer = MemoryBuffer::getMemBuffer(Text, BufferName); - Error E = Reader.read(*Buffer); - EXPECT_TRUE((bool)E); - return toString(std::move(E)); - } - - void read(StringRef Text, StringRef BufferName) { - Buffer = MemoryBuffer::getMemBuffer(Text, BufferName); - Error E = Reader.read(*Buffer); - EXPECT_FALSE((bool)E); - } -}; -} // unnamed namespace - -TEST_F(SymbolRemappingReaderTest, ParseErrors) { - EXPECT_EQ(readWithErrors("error", "foo.map"), - "foo.map:1: Expected 'kind mangled_name mangled_name', " - "found 'error'"); - - EXPECT_EQ(readWithErrors("error m1 m2", "foo.map"), - "foo.map:1: Invalid kind, expected 'name', 'type', or 'encoding', " - "found 'error'"); -} - -TEST_F(SymbolRemappingReaderTest, DemanglingErrors) { - EXPECT_EQ(readWithErrors("type i banana", "foo.map"), - "foo.map:1: Could not demangle 'banana' as a ; " - "invalid mangling?"); - EXPECT_EQ(readWithErrors("name i 1X", "foo.map"), - "foo.map:1: Could not demangle 'i' as a ; " - "invalid mangling?"); - EXPECT_EQ(readWithErrors("name 1X 1fv", "foo.map"), - "foo.map:1: Could not demangle '1fv' as a ; " - "invalid mangling?"); - EXPECT_EQ(readWithErrors("encoding 1fv 1f1gE", "foo.map"), - "foo.map:1: Could not demangle '1f1gE' as a ; " - "invalid mangling?"); -} - -TEST_F(SymbolRemappingReaderTest, BadMappingOrder) { - StringRef Map = R"( - # N::foo == M::bar - name N1N3fooE N1M3barE - - # N:: == M:: - name 1N 1M - )"; - EXPECT_EQ(readWithErrors(Map, "foo.map"), - "foo.map:6: Manglings '1N' and '1M' have both been used in prior " - "remappings. Move this remapping earlier in the file."); -} - -TEST_F(SymbolRemappingReaderTest, RemappingsAdded) { - StringRef Map = R"( - # A::foo == B::bar - name N1A3fooE N1B3barE - - # int == long - type i l - - # void f() = void g() - encoding 1fIiEvv 1gIiEvv - )"; - - read(Map, "foo.map"); - auto Key = Reader.insert("_ZN1B3bar3bazIiEEvv"); - EXPECT_NE(Key, SymbolRemappingReader::Key()); - EXPECT_EQ(Key, Reader.lookup("_ZN1A3foo3bazIlEEvv")); - EXPECT_NE(Key, Reader.lookup("_ZN1C3foo3bazIlEEvv")); - - Key = Reader.insert("_Z1fIiEvv"); - EXPECT_NE(Key, SymbolRemappingReader::Key()); - EXPECT_EQ(Key, Reader.lookup("_Z1gIlEvv")); -} diff --git a/llvm/utils/gn/secondary/llvm/lib/ProfileData/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/ProfileData/BUILD.gn --- a/llvm/utils/gn/secondary/llvm/lib/ProfileData/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/ProfileData/BUILD.gn @@ -14,11 +14,13 @@ "InstrProfCorrelator.cpp", "InstrProfReader.cpp", "InstrProfWriter.cpp", + "ItaniumManglingCanonicalizer.cpp", "MemProf.cpp", "ProfileSummaryBuilder.cpp", "RawMemProfReader.cpp", "SampleProf.cpp", "SampleProfReader.cpp", "SampleProfWriter.cpp", + "SymbolRemappingReader.cpp", ] } diff --git a/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn b/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn --- a/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/lib/Support/BUILD.gn @@ -89,7 +89,6 @@ "InstructionCost.cpp", "IntEqClasses.cpp", "IntervalMap.cpp", - "ItaniumManglingCanonicalizer.cpp", "JSON.cpp", "KnownBits.cpp", "LEB128.cpp", @@ -133,7 +132,6 @@ "StringRef.cpp", "StringSaver.cpp", "SuffixTree.cpp", - "SymbolRemappingReader.cpp", "SystemUtils.cpp", "TarWriter.cpp", "ThreadPool.cpp", diff --git a/llvm/utils/gn/secondary/llvm/tools/llvm-cxxmap/BUILD.gn b/llvm/utils/gn/secondary/llvm/tools/llvm-cxxmap/BUILD.gn --- a/llvm/utils/gn/secondary/llvm/tools/llvm-cxxmap/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/tools/llvm-cxxmap/BUILD.gn @@ -1,6 +1,7 @@ executable("llvm-cxxmap") { deps = [ "//llvm/lib/IR", + "//llvm/lib/ProfileData", "//llvm/lib/Support", "//llvm/lib/Target:TargetsToBuild", ] diff --git a/llvm/utils/gn/secondary/llvm/unittests/ProfileData/BUILD.gn b/llvm/utils/gn/secondary/llvm/unittests/ProfileData/BUILD.gn --- a/llvm/utils/gn/secondary/llvm/unittests/ProfileData/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/unittests/ProfileData/BUILD.gn @@ -11,7 +11,9 @@ "CoverageMappingTest.cpp", "InstrProfDataTest.cpp", "InstrProfTest.cpp", + "ItaniumManglingCanonicalizerTest.cpp", "MemProfTest.cpp", "SampleProfTest.cpp", + "SymbolRemappingReaderTest.cpp", ] } diff --git a/llvm/utils/gn/secondary/llvm/unittests/Support/BUILD.gn b/llvm/utils/gn/secondary/llvm/unittests/Support/BUILD.gn --- a/llvm/utils/gn/secondary/llvm/unittests/Support/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/unittests/Support/BUILD.gn @@ -49,7 +49,6 @@ "HashBuilderTest.cpp", "IndexedAccessorTest.cpp", "InstructionCostTest.cpp", - "ItaniumManglingCanonicalizerTest.cpp", "JSONTest.cpp", "KnownBitsTest.cpp", "LEB128Test.cpp", @@ -79,7 +78,6 @@ "SpecialCaseListTest.cpp", "SuffixTreeTest.cpp", "SwapByteOrderTest.cpp", - "SymbolRemappingReaderTest.cpp", "TarWriterTest.cpp", "TaskQueueTest.cpp", "ThreadPool.cpp", diff --git a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel --- a/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/llvm/BUILD.bazel @@ -3188,6 +3188,7 @@ copts = llvm_copts, stamp = 0, deps = [ + ":ProfileData", ":Support", ], )