17using llvm::itanium_demangle::ForwardTemplateReference;
18using llvm::itanium_demangle::Node;
19using llvm::itanium_demangle::NodeKind;
22struct FoldingSetNodeIDBuilder {
24 void operator()(
const Node *
P) {
ID.AddPointer(
P); }
25 void operator()(std::string_view Str) {
32 std::enable_if_t<std::is_integral_v<T> || std::is_enum_v<T>> operator()(
T V) {
33 ID.AddInteger((
unsigned long long)V);
35 void operator()(itanium_demangle::NodeArray
A) {
36 ID.AddInteger(
A.size());
42template<
typename ...T>
44 FoldingSetNodeIDBuilder Builder = {
ID};
46 int VisitInOrder[] = {
54template<
typename NodeT>
struct ProfileSpecificNode {
56 template<
typename ...T>
void operator()(
T ...V) {
63 template<
typename NodeT>
void operator()(
const NodeT *
N) {
64 N->match(ProfileSpecificNode<NodeT>{
ID});
73 N->visit(ProfileNode{
ID});
76class FoldingNodeAllocator {
80 itanium_demangle::Node *
getNode() {
81 return reinterpret_cast<itanium_demangle::Node *
>(
this + 1);
92 template <
typename T,
typename...
Args>
93 std::pair<Node *, bool> getOrCreateNode(
bool CreateNewNodes, Args &&... As) {
97 if (std::is_same<T, ForwardTemplateReference>::value) {
100 return {
new (RawAlloc.
Allocate(
sizeof(
T),
alignof(
T)))
101 T(std::forward<Args>(As)...),
110 return {
static_cast<T*
>(Existing->getNode()),
false};
113 return {
nullptr,
true};
115 static_assert(
alignof(
T) <=
alignof(NodeHeader),
116 "underaligned node header for specific node kind");
118 RawAlloc.
Allocate(
sizeof(NodeHeader) +
sizeof(
T),
alignof(NodeHeader));
119 NodeHeader *
New =
new (Storage) NodeHeader;
120 T *
Result =
new (
New->getNode())
T(std::forward<Args>(As)...);
125 template<
typename T,
typename...
Args>
126 Node *makeNode(Args &&...As) {
127 return getOrCreateNode<T>(
true, std::forward<Args>(As)...).first;
130 void *allocateNodeArray(
size_t sz) {
135class CanonicalizerAllocator :
public FoldingNodeAllocator {
136 Node *MostRecentlyCreated =
nullptr;
137 Node *TrackedNode =
nullptr;
138 bool TrackedNodeIsUsed =
false;
139 bool CreateNewNodes =
true;
142 template<
typename T,
typename ...Args>
Node *makeNodeSimple(Args &&...As) {
143 std::pair<Node *, bool>
Result =
144 getOrCreateNode<T>(CreateNewNodes, std::forward<Args>(As)...);
147 MostRecentlyCreated =
Result.first;
148 }
else if (
Result.first) {
153 "should never need multiple remap steps");
155 if (
Result.first == TrackedNode)
156 TrackedNodeIsUsed =
true;
162 template<
typename T>
struct MakeNodeImpl {
163 CanonicalizerAllocator &Self;
164 template<
typename ...Args>
Node *make(Args &&...As) {
165 return Self.makeNodeSimple<
T>(std::forward<Args>(As)...);
170 template<
typename T,
typename ...Args>
Node *makeNode(Args &&...As) {
171 return MakeNodeImpl<T>{*
this}.make(std::forward<Args>(As)...);
174 void reset() { MostRecentlyCreated =
nullptr; }
176 void setCreateNewNodes(
bool CNN) { CreateNewNodes = CNN; }
181 Remappings.
insert(std::make_pair(
A,
B));
184 bool isMostRecentlyCreated(
Node *
N)
const {
return MostRecentlyCreated ==
N; }
186 void trackUsesOf(
Node *
N) {
188 TrackedNodeIsUsed =
false;
190 bool trackedNodeIsUsed()
const {
return TrackedNodeIsUsed; }
195using CanonicalizingDemangler =
196 itanium_demangle::ManglingParser<CanonicalizerAllocator>;
209 auto &
Alloc =
P->Demangler.ASTAllocator;
210 Alloc.setCreateNewNodes(
true);
213 P->Demangler.reset(Str.begin(), Str.end());
222 if (Str.size() == 2 &&
P->Demangler.consumeIf(
"St"))
223 N =
P->Demangler.make<itanium_demangle::NameType>(
"std");
228 else if (Str.starts_with(
"S"))
230 N =
P->Demangler.parseType();
232 N =
P->Demangler.parseName();
237 N =
P->Demangler.parseType();
242 N =
P->Demangler.parseEncoding();
247 if (
P->Demangler.numLeft() != 0)
252 return std::make_pair(
N,
Alloc.isMostRecentlyCreated(
N));
255 Node *FirstNode, *SecondNode;
256 bool FirstIsNew, SecondIsNew;
258 std::tie(FirstNode, FirstIsNew) = Parse(
First);
262 Alloc.trackUsesOf(FirstNode);
263 std::tie(SecondNode, SecondIsNew) = Parse(Second);
268 if (FirstNode == SecondNode)
271 if (FirstIsNew && !
Alloc.trackedNodeIsUsed())
272 Alloc.addRemapping(FirstNode, SecondNode);
273 else if (SecondIsNew)
274 Alloc.addRemapping(SecondNode, FirstNode);
283 bool CreateNewNodes) {
284 Demangler.ASTAllocator.setCreateNewNodes(CreateNewNodes);
296 N =
Demangler.make<itanium_demangle::NameType>(
297 std::string_view(Mangling.
data(), Mangling.
size()));
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static msgpack::DocNode getNode(msgpack::DocNode DN, msgpack::Type Type, MCValue Val)
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)
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...
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
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>.
LLVM_ABI Key lookup(StringRef Mangling)
Find a canonical key for the specified mangling, if one has already been formed.
LLVM_ABI Key canonicalize(StringRef Mangling)
Form a canonical key for the specified mangling.
LLVM_ABI 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...
LLVM_ABI EquivalenceError addEquivalence(FragmentKind Kind, StringRef First, StringRef Second)
Add an equivalence between First and Second.
LLVM_ABI ~ItaniumManglingCanonicalizer()
StringRef - Represent a constant reference to a string, i.e.
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr size_t size() const
size - Get the string size.
constexpr 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.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
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.