17using llvm::itanium_demangle::ForwardTemplateReference;
18using llvm::itanium_demangle::Node;
19using llvm::itanium_demangle::NodeKind;
20using llvm::itanium_demangle::StringView;
23struct FoldingSetNodeIDBuilder {
25 void operator()(
const Node *
P) {
ID.AddPointer(
P); }
30 std::enable_if_t<std::is_integral_v<T> || std::is_enum_v<T>> operator()(
T V) {
31 ID.AddInteger((
unsigned long long)V);
33 void operator()(itanium_demangle::NodeArray
A) {
34 ID.AddInteger(
A.size());
40template<
typename ...T>
44 int VisitInOrder[] = {
52template<
typename NodeT>
struct ProfileSpecificNode {
54 template<
typename ...T>
void operator()(
T ...V) {
61 template<
typename NodeT>
void operator()(
const NodeT *
N) {
62 N->match(ProfileSpecificNode<NodeT>{
ID});
71 N->visit(ProfileNode{
ID});
74class FoldingNodeAllocator {
78 itanium_demangle::Node *getNode() {
79 return reinterpret_cast<itanium_demangle::Node *
>(
this + 1);
90 template <
typename T,
typename...
Args>
91 std::pair<Node *, bool> getOrCreateNode(
bool CreateNewNodes, Args &&... As) {
95 if (std::is_same<T, ForwardTemplateReference>::value) {
98 return {
new (RawAlloc.
Allocate(
sizeof(
T),
alignof(
T)))
99 T(std::forward<Args>(As)...),
108 return {
static_cast<T*
>(Existing->getNode()),
false};
111 return {
nullptr,
true};
113 static_assert(
alignof(
T) <=
alignof(NodeHeader),
114 "underaligned node header for specific node kind");
116 RawAlloc.
Allocate(
sizeof(NodeHeader) +
sizeof(
T),
alignof(NodeHeader));
117 NodeHeader *
New =
new (Storage) NodeHeader;
118 T *
Result =
new (
New->getNode())
T(std::forward<Args>(As)...);
123 template<
typename T,
typename...
Args>
124 Node *makeNode(Args &&...As) {
125 return getOrCreateNode<T>(
true, std::forward<Args>(As)...).first;
128 void *allocateNodeArray(
size_t sz) {
133class CanonicalizerAllocator :
public FoldingNodeAllocator {
134 Node *MostRecentlyCreated =
nullptr;
135 Node *TrackedNode =
nullptr;
136 bool TrackedNodeIsUsed =
false;
137 bool CreateNewNodes =
true;
140 template<
typename T,
typename ...Args>
Node *makeNodeSimple(Args &&...As) {
141 std::pair<Node *, bool>
Result =
142 getOrCreateNode<T>(CreateNewNodes, std::forward<Args>(As)...);
145 MostRecentlyCreated =
Result.first;
146 }
else if (
Result.first) {
151 "should never need multiple remap steps");
153 if (
Result.first == TrackedNode)
154 TrackedNodeIsUsed =
true;
160 template<
typename T>
struct MakeNodeImpl {
161 CanonicalizerAllocator &Self;
162 template<
typename ...Args>
Node *
make(Args &&...As) {
163 return Self.makeNodeSimple<
T>(std::forward<Args>(As)...);
168 template<
typename T,
typename ...Args>
Node *makeNode(Args &&...As) {
169 return MakeNodeImpl<T>{*
this}.make(std::forward<Args>(As)...);
172 void reset() { MostRecentlyCreated =
nullptr; }
174 void setCreateNewNodes(
bool CNN) { CreateNewNodes = CNN; }
179 Remappings.
insert(std::make_pair(
A,
B));
182 bool isMostRecentlyCreated(
Node *
N)
const {
return MostRecentlyCreated ==
N; }
184 void trackUsesOf(
Node *
N) {
186 TrackedNodeIsUsed =
false;
188 bool trackedNodeIsUsed()
const {
return TrackedNodeIsUsed; }
193using CanonicalizingDemangler =
194 itanium_demangle::ManglingParser<CanonicalizerAllocator>;
207 auto &
Alloc =
P->Demangler.ASTAllocator;
208 Alloc.setCreateNewNodes(
true);
211 P->Demangler.reset(Str.begin(), Str.end());
220 if (Str.size() == 2 &&
P->Demangler.consumeIf(
"St"))
221 N =
P->Demangler.make<itanium_demangle::NameType>(
"std");
226 else if (Str.startswith(
"S"))
228 N =
P->Demangler.parseType();
230 N =
P->Demangler.parseName();
235 N =
P->Demangler.parseType();
240 N =
P->Demangler.parseEncoding();
245 if (
P->Demangler.numLeft() != 0)
250 return std::make_pair(
N,
Alloc.isMostRecentlyCreated(
N));
253 Node *FirstNode, *SecondNode;
254 bool FirstIsNew, SecondIsNew;
256 std::tie(FirstNode, FirstIsNew) = Parse(First);
260 Alloc.trackUsesOf(FirstNode);
261 std::tie(SecondNode, SecondIsNew) = Parse(Second);
266 if (FirstNode == SecondNode)
269 if (FirstIsNew && !
Alloc.trackedNodeIsUsed())
270 Alloc.addRemapping(FirstNode, SecondNode);
271 else if (SecondIsNew)
272 Alloc.addRemapping(SecondNode, FirstNode);
281 bool CreateNewNodes) {
282 Demangler.ASTAllocator.setCreateNewNodes(CreateNewNodes);
294 N =
Demangler.make<itanium_demangle::NameType>(
This file defines the BumpPtrAllocator interface.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
This file defines the DenseMap class.
This file defines a hash set that can be used to remove duplication of nodes in a graph.
itanium_demangle::ManglingParser< DefaultAllocator > Demangler
static ItaniumManglingCanonicalizer::Key parseMaybeMangledName(CanonicalizingDemangler &Demangler, StringRef Mangling, bool CreateNewNodes)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Allocate memory in an ever growing pool, as if by bump-pointer.
LLVM_ATTRIBUTE_RETURNS_NONNULL void * Allocate(size_t Size, Align Alignment)
Allocate space at the specified alignment.
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Node - This class is used to maintain the singly linked bucket list in a folding set.
void InsertNode(T *N, void *InsertPos)
InsertNode - Insert the specified node into the folding set, knowing that it is not already in the fo...
T * FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos)
FindNodeOrInsertPos - Look up the node specified by ID.
FoldingSetNodeID - This class is used to gather all the unique data bits of a node.
FoldingSet - This template class is used to instantiate a specialized implementation of the folding s...
@ Encoding
The mangling fragment is an <encoding>.
@ Name
The mangling fragment is a <name> (or a predefined <substitution>).
@ Type
The mangling fragment is a <type>.
Key lookup(StringRef Mangling)
Find a canonical key for the specified mangling, if one has already been formed.
Key canonicalize(StringRef Mangling)
Form a canonical key for the specified mangling.
ItaniumManglingCanonicalizer()
@ InvalidFirstMangling
The first equivalent mangling is invalid.
@ InvalidSecondMangling
The second equivalent mangling is invalid.
@ ManglingAlreadyUsed
Both the equivalent manglings have already been used as components of some other mangling we've looke...
EquivalenceError addEquivalence(FragmentKind Kind, StringRef First, StringRef Second)
Add an equivalence between First and Second.
~ItaniumManglingCanonicalizer()
StringRef - Represent a constant reference to a string, i.e.
constexpr size_t size() const
size - Get the string size.
bool startswith(StringRef Prefix) const
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
This is an optimization pass for GlobalISel generic memory operations.
A forward-reference to a template argument that was not known at the point where the template paramet...
CanonicalizingDemangler Demangler
Determine the kind of a node from its type.