mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-12 13:38:21 +00:00
AsmPrinter: Convert DIE::Values to a linked list
Change `DIE::Values` to a singly linked list, where each node is allocated on a `BumpPtrAllocator`. In order to support `push_back()`, the list is circular, and points at the tail element instead of the head. I abstracted the core list logic out to `IntrusiveBackList` so that it can be reused for `DIE::Children`, which also cares about `push_back()`. This drops llc memory usage from 799 MB down to 735 MB, about 8%. (I'm looking at `llc` memory usage on `verify-uselistorder.lto.opt.bc`; see r236629 for details.) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@240733 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -15,6 +15,8 @@
|
||||
#define LLVM_LIB_CODEGEN_ASMPRINTER_DIE_H
|
||||
|
||||
#include "llvm/ADT/FoldingSet.h"
|
||||
#include "llvm/ADT/PointerIntPair.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/CodeGen/DwarfStringPoolEntry.h"
|
||||
#include "llvm/Support/Dwarf.h"
|
||||
@ -448,6 +450,162 @@ public:
|
||||
#endif
|
||||
};
|
||||
|
||||
struct IntrusiveBackListNode {
|
||||
PointerIntPair<IntrusiveBackListNode *, 1> Next;
|
||||
IntrusiveBackListNode() : Next(this, true) {}
|
||||
|
||||
IntrusiveBackListNode *getNext() const {
|
||||
return Next.getInt() ? nullptr : Next.getPointer();
|
||||
}
|
||||
};
|
||||
|
||||
struct IntrusiveBackListBase {
|
||||
typedef IntrusiveBackListNode Node;
|
||||
Node *Last = nullptr;
|
||||
|
||||
bool empty() const { return !Last; }
|
||||
void push_back(Node &N) {
|
||||
assert(N.Next.getPointer() == &N && "Expected unlinked node");
|
||||
assert(N.Next.getInt() == true && "Expected unlinked node");
|
||||
|
||||
if (Last) {
|
||||
N.Next = Last->Next;
|
||||
Last->Next.setPointerAndInt(&N, false);
|
||||
}
|
||||
Last = &N;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T> class IntrusiveBackList : IntrusiveBackListBase {
|
||||
public:
|
||||
using IntrusiveBackListBase::empty;
|
||||
void push_back(T &N) { IntrusiveBackListBase::push_back(N); }
|
||||
T &back() { return *static_cast<T *>(Last); }
|
||||
const T &back() const { return *static_cast<T *>(Last); }
|
||||
|
||||
class const_iterator;
|
||||
class iterator
|
||||
: public iterator_facade_base<iterator, std::forward_iterator_tag, T> {
|
||||
friend class const_iterator;
|
||||
Node *N = nullptr;
|
||||
|
||||
public:
|
||||
iterator() = default;
|
||||
explicit iterator(T *N) : N(N) {}
|
||||
|
||||
iterator &operator++() {
|
||||
N = N->getNext();
|
||||
return *this;
|
||||
}
|
||||
|
||||
explicit operator bool() const { return N; }
|
||||
T &operator*() const { return *static_cast<T *>(N); }
|
||||
|
||||
bool operator==(const iterator &X) const { return N == X.N; }
|
||||
bool operator!=(const iterator &X) const { return N != X.N; }
|
||||
};
|
||||
|
||||
class const_iterator
|
||||
: public iterator_facade_base<const_iterator, std::forward_iterator_tag,
|
||||
const T> {
|
||||
const Node *N = nullptr;
|
||||
|
||||
public:
|
||||
const_iterator() = default;
|
||||
const_iterator(iterator X) : N(X.N) {}
|
||||
explicit const_iterator(const T *N) : N(N) {}
|
||||
|
||||
const_iterator &operator++() {
|
||||
N = N->getNext();
|
||||
return *this;
|
||||
}
|
||||
|
||||
explicit operator bool() const { return N; }
|
||||
const T &operator*() const { return *static_cast<const T *>(N); }
|
||||
|
||||
bool operator==(const const_iterator &X) const { return N == X.N; }
|
||||
bool operator!=(const const_iterator &X) const { return N != X.N; }
|
||||
};
|
||||
|
||||
iterator begin() {
|
||||
return Last ? iterator(static_cast<T *>(Last->Next.getPointer())) : end();
|
||||
}
|
||||
const_iterator begin() const {
|
||||
return const_cast<IntrusiveBackList *>(this)->begin();
|
||||
}
|
||||
iterator end() { return iterator(); }
|
||||
const_iterator end() const { return const_iterator(); }
|
||||
|
||||
static iterator toIterator(T &N) { return iterator(&N); }
|
||||
static const_iterator toIterator(const T &N) { return const_iterator(&N); }
|
||||
};
|
||||
|
||||
/// A list of DIE values.
|
||||
///
|
||||
/// This is a singly-linked list, but instead of reversing the order of
|
||||
/// insertion, we keep a pointer to the back of the list so we can push in
|
||||
/// order.
|
||||
class DIEValueList {
|
||||
struct Node : IntrusiveBackListNode {
|
||||
DIEValue V;
|
||||
explicit Node(DIEValue V) : V(V) {}
|
||||
};
|
||||
|
||||
typedef IntrusiveBackList<Node> ListTy;
|
||||
ListTy List;
|
||||
|
||||
public:
|
||||
bool empty() const { return List.empty(); }
|
||||
|
||||
class const_iterator;
|
||||
class iterator
|
||||
: public iterator_adaptor_base<iterator, ListTy::iterator,
|
||||
std::forward_iterator_tag, DIEValue> {
|
||||
friend class const_iterator;
|
||||
typedef iterator_adaptor_base<iterator, ListTy::iterator,
|
||||
std::forward_iterator_tag,
|
||||
DIEValue> iterator_adaptor;
|
||||
|
||||
public:
|
||||
iterator() = default;
|
||||
explicit iterator(ListTy::iterator X) : iterator_adaptor(X) {}
|
||||
|
||||
explicit operator bool() const { return bool(wrapped()); }
|
||||
DIEValue &operator*() const { return wrapped()->V; }
|
||||
};
|
||||
|
||||
class const_iterator
|
||||
: public iterator_adaptor_base<const_iterator, ListTy::const_iterator,
|
||||
std::forward_iterator_tag,
|
||||
const DIEValue> {
|
||||
typedef iterator_adaptor_base<const_iterator, ListTy::const_iterator,
|
||||
std::forward_iterator_tag,
|
||||
const DIEValue> iterator_adaptor;
|
||||
|
||||
public:
|
||||
const_iterator() = default;
|
||||
const_iterator(DIEValueList::iterator X) : iterator_adaptor(X.wrapped()) {}
|
||||
explicit const_iterator(ListTy::const_iterator X) : iterator_adaptor(X) {}
|
||||
|
||||
explicit operator bool() const { return bool(wrapped()); }
|
||||
const DIEValue &operator*() const { return wrapped()->V; }
|
||||
};
|
||||
|
||||
iterator insert(BumpPtrAllocator &Alloc, DIEValue V) {
|
||||
List.push_back(*new (Alloc) Node(V));
|
||||
return iterator(ListTy::toIterator(List.back()));
|
||||
}
|
||||
template <class... Ts>
|
||||
iterator emplace(BumpPtrAllocator &Alloc, Ts &&... Args) {
|
||||
return insert(Alloc, DIEValue(std::forward<Ts>(Args)...));
|
||||
}
|
||||
|
||||
iterator begin() { return iterator(List.begin()); }
|
||||
iterator end() { return iterator(List.end()); }
|
||||
const_iterator begin() const { return const_iterator(List.begin()); }
|
||||
const_iterator end() const { return const_iterator(List.end()); }
|
||||
};
|
||||
|
||||
//===--------------------------------------------------------------------===//
|
||||
/// DIE - A structured debug information entry. Has an abbreviation which
|
||||
/// describes its organization.
|
||||
@ -481,7 +639,7 @@ protected:
|
||||
|
||||
/// Attribute values.
|
||||
///
|
||||
SmallVector<DIEValue, 12> Values;
|
||||
DIEValueList Values;
|
||||
|
||||
protected:
|
||||
DIE() : Offset(0), Size(0), Parent(nullptr) {}
|
||||
@ -504,19 +662,20 @@ public:
|
||||
return llvm::make_range(Children.begin(), Children.end());
|
||||
}
|
||||
|
||||
typedef SmallVectorImpl<DIEValue>::const_iterator value_iterator;
|
||||
typedef DIEValueList::iterator value_iterator;
|
||||
typedef iterator_range<value_iterator> value_range;
|
||||
|
||||
value_iterator values_begin() const { return Values.begin(); }
|
||||
value_iterator values_end() const { return Values.end(); }
|
||||
value_range values() const {
|
||||
return llvm::make_range(values_begin(), values_end());
|
||||
value_range values() {
|
||||
return llvm::make_range(Values.begin(), Values.end());
|
||||
}
|
||||
|
||||
void setValue(unsigned I, DIEValue New) {
|
||||
assert(I < Values.size());
|
||||
Values[I] = New;
|
||||
typedef DIEValueList::const_iterator const_value_iterator;
|
||||
typedef iterator_range<const_value_iterator> const_value_range;
|
||||
|
||||
const_value_range values() const {
|
||||
return llvm::make_range(Values.begin(), Values.end());
|
||||
}
|
||||
|
||||
DIE *getParent() const { return Parent; }
|
||||
|
||||
/// Generate the abbreviation for this DIE.
|
||||
@ -539,10 +698,13 @@ public:
|
||||
|
||||
/// addValue - Add a value and attributes to a DIE.
|
||||
///
|
||||
void addValue(DIEValue Value) { Values.push_back(Value); }
|
||||
value_iterator addValue(BumpPtrAllocator &Alloc, DIEValue Value) {
|
||||
return Values.insert(Alloc, Value);
|
||||
}
|
||||
template <class T>
|
||||
void addValue(dwarf::Attribute Attribute, dwarf::Form Form, T &&Value) {
|
||||
Values.emplace_back(Attribute, Form, std::forward<T>(Value));
|
||||
value_iterator addValue(BumpPtrAllocator &Alloc, dwarf::Attribute Attribute,
|
||||
dwarf::Form Form, T &&Value) {
|
||||
return Values.emplace(Alloc, Attribute, Form, std::forward<T>(Value));
|
||||
}
|
||||
|
||||
/// addChild - Add a child to the DIE.
|
||||
|
Reference in New Issue
Block a user