27 struct FoldingSetNodeIDBuilder {
34 typename std::enable_if<std::is_integral<T>::value ||
35 std::is_enum<T>::value>
::type 52 for (
const Node *
N : A)
57 template<
typename ...T>
59 FoldingSetNodeIDBuilder Builder = {ID};
61 int VisitInOrder[] = {
69 template<
typename NodeT>
struct ProfileSpecificNode {
71 template<
typename ...T>
void operator()(
T ...V) {
78 template<
typename NodeT>
void operator()(
const NodeT *
N) {
79 N->match(ProfileSpecificNode<NodeT>{ID});
88 N->
visit(ProfileNode{ID});
91 class FoldingNodeAllocator {
107 template <
typename T,
typename...
Args>
108 std::pair<Node *, bool> getOrCreateNode(
bool CreateNewNodes,
Args &&... As) {
112 if (std::is_same<T, ForwardTemplateReference>::value) {
115 return {
new (RawAlloc.
Allocate(
sizeof(
T),
alignof(
T)))
116 T(std::forward<Args>(As)...),
125 return {
static_cast<T*
>(Existing->getNode()),
false};
128 return {
nullptr,
true};
130 static_assert(
alignof(
T) <=
alignof(NodeHeader),
131 "underaligned node header for specific node kind");
133 RawAlloc.
Allocate(
sizeof(NodeHeader) +
sizeof(
T),
alignof(NodeHeader));
134 NodeHeader *
New =
new (Storage) NodeHeader;
135 T *
Result =
new (New->getNode())
T(std::forward<Args>(As)...);
137 return {Result,
true};
140 template<
typename T,
typename...
Args>
142 return getOrCreateNode<T>(
true, std::forward<Args>(As)...).first;
145 void *allocateNodeArray(
size_t sz) {
150 class CanonicalizerAllocator :
public FoldingNodeAllocator {
151 Node *MostRecentlyCreated =
nullptr;
152 Node *TrackedNode =
nullptr;
153 bool TrackedNodeIsUsed =
false;
154 bool CreateNewNodes =
true;
157 template<
typename T,
typename ...Args>
Node *makeNodeSimple(
Args &&...As) {
158 std::pair<Node *, bool> Result =
159 getOrCreateNode<T>(CreateNewNodes, std::forward<Args>(As)...);
162 MostRecentlyCreated = Result.first;
163 }
else if (Result.first) {
165 if (
auto *N = Remappings.
lookup(Result.first)) {
168 "should never need multiple remap steps");
170 if (Result.first == TrackedNode)
171 TrackedNodeIsUsed =
true;
177 template<
typename T>
struct MakeNodeImpl {
178 CanonicalizerAllocator &Self;
180 return Self.makeNodeSimple<
T>(std::forward<Args>(As)...);
185 template<
typename T,
typename ...Args>
Node *makeNode(
Args &&...As) {
186 return MakeNodeImpl<T>{*
this}.make(std::forward<Args>(As)...);
189 void reset() { MostRecentlyCreated =
nullptr; }
191 void setCreateNewNodes(
bool CNN) { CreateNewNodes = CNN; }
196 Remappings.
insert(std::make_pair(A, B));
199 bool isMostRecentlyCreated(
Node *N)
const {
return MostRecentlyCreated ==
N; }
201 void trackUsesOf(
Node *N) {
203 TrackedNodeIsUsed =
false;
205 bool trackedNodeIsUsed()
const {
return TrackedNodeIsUsed; }
211 struct CanonicalizerAllocator::MakeNodeImpl<
212 itanium_demangle::StdQualifiedName> {
213 CanonicalizerAllocator &Self;
224 using CanonicalizingDemangler =
238 auto &Alloc = P->Demangler.ASTAllocator;
239 Alloc.setCreateNewNodes(
true);
242 P->Demangler.reset(Str.
begin(), Str.
end());
251 if (Str.
size() == 2 && P->Demangler.consumeIf(
"St"))
257 else if (Str.startswith(
"S"))
259 N = P->Demangler.parseType();
261 N = P->Demangler.parseName();
266 N = P->Demangler.parseType();
271 N = P->Demangler.parseEncoding();
276 if (P->Demangler.numLeft() != 0)
281 return std::make_pair(N, Alloc.isMostRecentlyCreated(N));
284 Node *FirstNode, *SecondNode;
285 bool FirstIsNew, SecondIsNew;
287 std::tie(FirstNode, FirstIsNew) = Parse(First);
291 Alloc.trackUsesOf(FirstNode);
292 std::tie(SecondNode, SecondIsNew) = Parse(Second);
297 if (FirstNode == SecondNode)
300 if (FirstIsNew && !Alloc.trackedNodeIsUsed())
301 Alloc.addRemapping(FirstNode, SecondNode);
302 else if (SecondIsNew)
303 Alloc.addRemapping(SecondNode, FirstNode);
312 P->Demangler.ASTAllocator.setCreateNewNodes(
true);
313 P->Demangler.reset(Mangling.
begin(), Mangling.
end());
314 return reinterpret_cast<Key>(P->Demangler.parse());
319 P->Demangler.ASTAllocator.setCreateNewNodes(
false);
320 P->Demangler.reset(Mangling.
begin(), Mangling.
end());
321 return reinterpret_cast<Key>(P->Demangler.parse());
The first equivalent mangling is invalid.
void AddPointer(const void *Ptr)
Add* - Add various data types to Bit data.
void visit(Fn F) const
Visit the most-derived object corresponding to this object.
This class represents lattice values for constants.
T * FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos)
FindNodeOrInsertPos - Look up the node specified by ID.
This file defines the MallocAllocator and BumpPtrAllocator interfaces.
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
void AddInteger(signed I)
The second equivalent mangling is invalid.
void InsertNode(T *N, void *InsertPos)
InsertNode - Insert the specified node into the folding set, knowing that it is not already in the fo...
const char * begin() const
iterator find(const_arg_type_t< KeyT > Val)
FoldingSetNodeID - This class is used to gather all the unique data bits of a node.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
Allocate memory in an ever growing pool, as if by bump-pointer.
LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void * Allocate(size_t Size, size_t Alignment)
Allocate space at the specified alignment.
A forward-reference to a template argument that was not known at the point where the template paramet...
FoldingSet - This template class is used to instantiate a specialized implementation of the folding s...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
The mangling fragment is an <encoding>.
Key lookup(StringRef Mangling)
Find a canonical key for the specified mangling, if one has already been formed.
Both the equivalent manglings have already been used as components of some other mangling we've looke...
~ItaniumManglingCanonicalizer()
ItaniumManglingCanonicalizer()
Node - This class is used to maintain the singly linked bucket list in a folding set.
StringView asString() const
void AddString(StringRef String)
The mangling fragment is a <name> (or a predefined <substitution>).
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...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
EquivalenceError addEquivalence(FragmentKind Kind, StringRef First, StringRef Second)
Add an equivalence between First and Second.
const Node * asNode() const
StringRef - Represent a constant reference to a string, i.e.
The mangling fragment is a <type>.
Determine the kind of a node from its type.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Key canonicalize(StringRef Mangling)
Form a canonical key for the specified mangling.