Go to the documentation of this file.
17 using llvm::itanium_demangle::ForwardTemplateReference;
18 using llvm::itanium_demangle::Node;
20 using llvm::itanium_demangle::StringView;
23 struct FoldingSetNodeIDBuilder {
25 void operator()(
const Node *
P) {
ID.AddPointer(
P); }
26 void operator()(StringView Str) {
30 std::enable_if_t<std::is_integral<T>::value || std::is_enum<T>::value>
32 ID.AddInteger((
unsigned long long)V);
34 void operator()(itanium_demangle::NodeArray A) {
35 ID.AddInteger(
A.size());
36 for (
const Node *
N : A)
41 template<
typename ...T>
45 int VisitInOrder[] = {
53 template<
typename NodeT>
struct ProfileSpecificNode {
55 template<
typename ...T>
void operator()(
T ...V) {
62 template<
typename NodeT>
void operator()(
const NodeT *
N) {
63 N->match(ProfileSpecificNode<NodeT>{
ID});
67 template<>
void ProfileNode::operator()(
const ForwardTemplateReference *
N) {
72 N->visit(ProfileNode{
ID});
75 class FoldingNodeAllocator {
79 itanium_demangle::Node *getNode() {
80 return reinterpret_cast<itanium_demangle::Node *
>(
this + 1);
91 template <
typename T,
typename...
Args>
92 std::pair<Node *, bool> getOrCreateNode(
bool CreateNewNodes,
Args &&... As) {
96 if (std::is_same<T, ForwardTemplateReference>::value) {
99 return {
new (RawAlloc.
Allocate(
sizeof(
T),
alignof(
T)))
100 T(std::forward<Args>(As)...),
109 return {
static_cast<T*
>(Existing->getNode()),
false};
112 return {
nullptr,
true};
114 static_assert(
alignof(
T) <=
alignof(NodeHeader),
115 "underaligned node header for specific node kind");
117 RawAlloc.
Allocate(
sizeof(NodeHeader) +
sizeof(
T),
alignof(NodeHeader));
118 NodeHeader *
New =
new (Storage) NodeHeader;
119 T *
Result =
new (
New->getNode())
T(std::forward<Args>(As)...);
124 template<
typename T,
typename...
Args>
125 Node *makeNode(
Args &&...As) {
126 return getOrCreateNode<T>(
true, std::forward<Args>(As)...).first;
129 void *allocateNodeArray(
size_t sz) {
130 return RawAlloc.
Allocate(
sizeof(Node *) * sz,
alignof(Node *));
134 class CanonicalizerAllocator :
public FoldingNodeAllocator {
135 Node *MostRecentlyCreated =
nullptr;
136 Node *TrackedNode =
nullptr;
137 bool TrackedNodeIsUsed =
false;
138 bool CreateNewNodes =
true;
141 template<
typename T,
typename ...Args> Node *makeNodeSimple(
Args &&...As) {
142 std::pair<Node *, bool>
Result =
143 getOrCreateNode<T>(CreateNewNodes, std::forward<Args>(As)...);
146 MostRecentlyCreated =
Result.first;
147 }
else if (
Result.first) {
152 "should never need multiple remap steps");
154 if (
Result.first == TrackedNode)
155 TrackedNodeIsUsed =
true;
161 template<
typename T>
struct MakeNodeImpl {
162 CanonicalizerAllocator &Self;
163 template<
typename ...Args> Node *
make(
Args &&...As) {
164 return Self.makeNodeSimple<
T>(std::forward<Args>(As)...);
169 template<
typename T,
typename ...Args> Node *makeNode(
Args &&...As) {
170 return MakeNodeImpl<T>{*
this}.make(std::forward<Args>(As)...);
173 void reset() { MostRecentlyCreated =
nullptr; }
175 void setCreateNewNodes(
bool CNN) { CreateNewNodes = CNN; }
177 void addRemapping(Node *A, Node *
B) {
180 Remappings.
insert(std::make_pair(A,
B));
183 bool isMostRecentlyCreated(Node *
N)
const {
return MostRecentlyCreated ==
N; }
185 void trackUsesOf(Node *
N) {
187 TrackedNodeIsUsed =
false;
189 bool trackedNodeIsUsed()
const {
return TrackedNodeIsUsed; }
194 using CanonicalizingDemangler =
195 itanium_demangle::ManglingParser<CanonicalizerAllocator>;
208 auto &
Alloc =
P->Demangler.ASTAllocator;
209 Alloc.setCreateNewNodes(
true);
212 P->Demangler.reset(Str.begin(), Str.end());
221 if (Str.size() == 2 &&
P->Demangler.consumeIf(
"St"))
227 else if (Str.startswith(
"S"))
229 N =
P->Demangler.parseType();
231 N =
P->Demangler.parseName();
236 N =
P->Demangler.parseType();
241 N =
P->Demangler.parseEncoding();
246 if (
P->Demangler.numLeft() != 0)
251 return std::make_pair(
N,
Alloc.isMostRecentlyCreated(
N));
254 Node *FirstNode, *SecondNode;
255 bool FirstIsNew, SecondIsNew;
257 std::tie(FirstNode, FirstIsNew) = Parse(
First);
261 Alloc.trackUsesOf(FirstNode);
262 std::tie(SecondNode, SecondIsNew) = Parse(Second);
267 if (FirstNode == SecondNode)
270 if (FirstIsNew && !
Alloc.trackedNodeIsUsed())
271 Alloc.addRemapping(FirstNode, SecondNode);
272 else if (SecondIsNew)
273 Alloc.addRemapping(SecondNode, FirstNode);
282 bool CreateNewNodes) {
283 Demangler.ASTAllocator.setCreateNewNodes(CreateNewNodes);
296 StringView(Mangling.
data(), Mangling.
size()));
This is an optimization pass for GlobalISel generic memory operations.
@ Type
The mangling fragment is a <type>.
llvm::DenseMapBase< SmallDenseMap< KeyT, ValueT, 4, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::lookup 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...
static ItaniumManglingCanonicalizer::Key parseMaybeMangledName(CanonicalizingDemangler &Demangler, StringRef Mangling, bool CreateNewNodes)
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
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.
ItaniumManglingCanonicalizer()
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM ID Predecessors according to mbb< bb27, 0x8b0a7c0 > Note ADDri is not a two address instruction its result reg1037 is an operand of the PHI node in bb76 and its operand reg1039 is the result of the PHI node We should treat it as a two address code and make sure the ADDri is scheduled after any node that reads reg1039 Use info(i.e. register scavenger) to assign it a free register to allow reuse the collector could move the objects and invalidate the derived pointer This is bad enough in the first but safe points can crop up unpredictably **array_addr i32 n y store obj * new
itanium_demangle::ManglingParser< DefaultAllocator > Demangler
CanonicalizingDemangler Demangler
bool startswith(StringRef Prefix) const
Check if this string starts with the given Prefix.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
into llvm powi allowing the code generator to produce balanced multiplication trees First
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
~ItaniumManglingCanonicalizer()
@ Name
The mangling fragment is a <name> (or a predefined <substitution>).
Allocate memory in an ever growing pool, as if by bump-pointer.
@ Encoding
The mangling fragment is an <encoding>.
llvm::DenseMapBase< SmallDenseMap< KeyT, ValueT, 4, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::find iterator find(const_arg_type_t< KeyT > Val)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
@ InvalidSecondMangling
The second equivalent mangling is invalid.
FoldingSet - This template class is used to instantiate a specialized implementation of the folding s...
StringRef - Represent a constant reference to a string, i.e.
Node - This class is used to maintain the singly linked bucket list in a folding set.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ InvalidFirstMangling
The first equivalent mangling is invalid.
FoldingSetNodeID - This class is used to gather all the unique data bits of a node.
llvm::DenseMapBase< SmallDenseMap< KeyT, ValueT, 4, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::insert std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
constexpr size_t size() const
size - Get the string size.
llvm::DenseMapBase< SmallDenseMap< KeyT, ValueT, 4, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >, KeyT, ValueT, DenseMapInfo< KeyT >, llvm::detail::DenseMapPair< KeyT, ValueT > >::end iterator end()
LLVM_ATTRIBUTE_RETURNS_NONNULL void * Allocate(size_t Size, Align Alignment)
Allocate space at the specified alignment.
@ ManglingAlreadyUsed
Both the equivalent manglings have already been used as components of some other mangling we've looke...
Key canonicalize(StringRef Mangling)
Form a canonical key for the specified mangling.
EquivalenceError addEquivalence(FragmentKind Kind, StringRef First, StringRef Second)
Add an equivalence between First and Second.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
Key lookup(StringRef Mangling)
Find a canonical key for the specified mangling, if one has already been formed.