2017-02-17 01:00:09 +01:00
|
|
|
//===- llvm/SymbolTableListTraits.h - Traits for iplist ---------*- C++ -*-===//
|
2005-04-21 22:19:05 +02:00
|
|
|
//
|
2003-10-20 22:19:47 +02:00
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
2007-12-29 20:59:42 +01:00
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
2005-04-21 22:19:05 +02:00
|
|
|
//
|
2003-10-20 22:19:47 +02:00
|
|
|
//===----------------------------------------------------------------------===//
|
2002-06-25 18:12:52 +02:00
|
|
|
//
|
|
|
|
// This file defines a generic class that is used to implement the automatic
|
|
|
|
// symbol table manipulation that occurs when you put (for example) a named
|
|
|
|
// instruction into a basic block.
|
|
|
|
//
|
|
|
|
// The way that this is implemented is by using a special traits class with the
|
|
|
|
// intrusive list that makes up the list of instructions in a basic block. When
|
|
|
|
// a new element is added to the list of instructions, the traits class is
|
|
|
|
// notified, allowing the symbol table to be updated.
|
|
|
|
//
|
|
|
|
// This generic class implements the traits class. It must be generic so that
|
|
|
|
// it can work for all uses it, which include lists of instructions, basic
|
|
|
|
// blocks, arguments, functions, global variables, etc...
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2013-01-10 01:45:19 +01:00
|
|
|
#ifndef LLVM_IR_SYMBOLTABLELISTTRAITS_H
|
|
|
|
#define LLVM_IR_SYMBOLTABLELISTTRAITS_H
|
2002-06-25 18:12:52 +02:00
|
|
|
|
2008-07-28 23:51:04 +02:00
|
|
|
#include "llvm/ADT/ilist.h"
|
2017-02-17 01:00:09 +01:00
|
|
|
#include "llvm/ADT/simple_ilist.h"
|
|
|
|
#include <cstddef>
|
2008-07-28 23:51:04 +02:00
|
|
|
|
2003-11-11 23:41:34 +01:00
|
|
|
namespace llvm {
|
2015-09-22 13:13:55 +02:00
|
|
|
|
2015-10-07 22:05:10 +02:00
|
|
|
class Argument;
|
|
|
|
class BasicBlock;
|
|
|
|
class Function;
|
|
|
|
class GlobalAlias;
|
2016-04-07 14:32:19 +02:00
|
|
|
class GlobalIFunc;
|
2017-02-17 01:00:09 +01:00
|
|
|
class GlobalVariable;
|
|
|
|
class Instruction;
|
2015-10-07 22:05:10 +02:00
|
|
|
class Module;
|
2017-02-17 01:00:09 +01:00
|
|
|
class ValueSymbolTable;
|
|
|
|
|
|
|
|
/// Template metafunction to get the parent type for a symbol table list.
|
|
|
|
///
|
|
|
|
/// Implementations create a typedef called \c type so that we only need a
|
|
|
|
/// single template parameter for the list and traits.
|
|
|
|
template <typename NodeTy> struct SymbolTableListParentType {};
|
|
|
|
|
2015-10-07 22:05:10 +02:00
|
|
|
#define DEFINE_SYMBOL_TABLE_PARENT_TYPE(NODE, PARENT) \
|
2017-05-13 00:25:07 +02:00
|
|
|
template <> struct SymbolTableListParentType<NODE> { using type = PARENT; };
|
2015-10-07 22:05:10 +02:00
|
|
|
DEFINE_SYMBOL_TABLE_PARENT_TYPE(Instruction, BasicBlock)
|
|
|
|
DEFINE_SYMBOL_TABLE_PARENT_TYPE(BasicBlock, Function)
|
|
|
|
DEFINE_SYMBOL_TABLE_PARENT_TYPE(Argument, Function)
|
|
|
|
DEFINE_SYMBOL_TABLE_PARENT_TYPE(Function, Module)
|
|
|
|
DEFINE_SYMBOL_TABLE_PARENT_TYPE(GlobalVariable, Module)
|
|
|
|
DEFINE_SYMBOL_TABLE_PARENT_TYPE(GlobalAlias, Module)
|
2016-04-07 14:32:19 +02:00
|
|
|
DEFINE_SYMBOL_TABLE_PARENT_TYPE(GlobalIFunc, Module)
|
2015-10-07 22:05:10 +02:00
|
|
|
#undef DEFINE_SYMBOL_TABLE_PARENT_TYPE
|
|
|
|
|
|
|
|
template <typename NodeTy> class SymbolTableList;
|
|
|
|
|
2009-02-27 10:33:37 +01:00
|
|
|
// ValueSubClass - The type of objects that I hold, e.g. Instruction.
|
|
|
|
// ItemParentClass - The type of object that owns the list, e.g. BasicBlock.
|
2002-06-25 18:12:52 +02:00
|
|
|
//
|
2015-10-07 22:05:10 +02:00
|
|
|
template <typename ValueSubClass>
|
2016-08-30 20:40:47 +02:00
|
|
|
class SymbolTableListTraits : public ilist_alloc_traits<ValueSubClass> {
|
2017-05-13 00:25:07 +02:00
|
|
|
using ListTy = SymbolTableList<ValueSubClass>;
|
|
|
|
using iterator = typename simple_ilist<ValueSubClass>::iterator;
|
|
|
|
using ItemParentClass =
|
|
|
|
typename SymbolTableListParentType<ValueSubClass>::type;
|
2015-10-07 22:05:10 +02:00
|
|
|
|
2002-06-25 18:12:52 +02:00
|
|
|
public:
|
2017-02-17 01:00:09 +01:00
|
|
|
SymbolTableListTraits() = default;
|
2002-06-25 18:12:52 +02:00
|
|
|
|
2015-10-07 00:14:06 +02:00
|
|
|
private:
|
2007-04-17 06:04:14 +02:00
|
|
|
/// getListOwner - Return the object that owns this list. If this is a list
|
|
|
|
/// of instructions, it returns the BasicBlock that owns them.
|
|
|
|
ItemParentClass *getListOwner() {
|
2014-04-09 08:08:46 +02:00
|
|
|
size_t Offset(size_t(&((ItemParentClass*)nullptr->*ItemParentClass::
|
|
|
|
getSublistAccess(static_cast<ValueSubClass*>(nullptr)))));
|
2015-10-07 22:05:10 +02:00
|
|
|
ListTy *Anchor(static_cast<ListTy *>(this));
|
2009-03-07 11:00:35 +01:00
|
|
|
return reinterpret_cast<ItemParentClass*>(reinterpret_cast<char*>(Anchor)-
|
|
|
|
Offset);
|
2007-04-17 06:04:14 +02:00
|
|
|
}
|
2002-06-25 18:12:52 +02:00
|
|
|
|
2015-10-07 22:05:10 +02:00
|
|
|
static ListTy &getList(ItemParentClass *Par) {
|
2014-04-09 08:08:46 +02:00
|
|
|
return Par->*(Par->getSublistAccess((ValueSubClass*)nullptr));
|
2009-03-07 13:33:24 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static ValueSymbolTable *getSymTab(ItemParentClass *Par) {
|
2014-04-09 08:08:46 +02:00
|
|
|
return Par ? toPtr(Par->getValueSymbolTable()) : nullptr;
|
2009-03-07 13:33:24 +01:00
|
|
|
}
|
2009-03-07 11:49:57 +01:00
|
|
|
|
2015-10-06 23:31:07 +02:00
|
|
|
public:
|
2002-06-25 18:12:52 +02:00
|
|
|
void addNodeToList(ValueSubClass *V);
|
|
|
|
void removeNodeFromList(ValueSubClass *V);
|
ADT: Give ilist<T>::reverse_iterator a handle to the current node
Reverse iterators to doubly-linked lists can be simpler (and cheaper)
than std::reverse_iterator. Make it so.
In particular, change ilist<T>::reverse_iterator so that it is *never*
invalidated unless the node it references is deleted. This matches the
guarantees of ilist<T>::iterator.
(Note: MachineBasicBlock::iterator is *not* an ilist iterator, but a
MachineInstrBundleIterator<MachineInstr>. This commit does not change
MachineBasicBlock::reverse_iterator, but it does update
MachineBasicBlock::reverse_instr_iterator. See note at end of commit
message for details on bundle iterators.)
Given the list (with the Sentinel showing twice for simplicity):
[Sentinel] <-> A <-> B <-> [Sentinel]
the following is now true:
1. begin() represents A.
2. begin() holds the pointer for A.
3. end() represents [Sentinel].
4. end() holds the poitner for [Sentinel].
5. rbegin() represents B.
6. rbegin() holds the pointer for B.
7. rend() represents [Sentinel].
8. rend() holds the pointer for [Sentinel].
The changes are #6 and #8. Here are some properties from the old
scheme (which used std::reverse_iterator):
- rbegin() held the pointer for [Sentinel] and rend() held the pointer
for A;
- operator*() cost two dereferences instead of one;
- converting from a valid iterator to its valid reverse_iterator
involved a confusing increment; and
- "RI++->erase()" left RI invalid. The unintuitive replacement was
"RI->erase(), RE = end()".
With vector-like data structures these properties are hard to avoid
(since past-the-beginning is not a valid pointer), and don't impose a
real cost (since there's still only one dereference, and all iterators
are invalidated on erase). But with lists, this was a poor design.
Specifically, the following code (which obviously works with normal
iterators) now works with ilist::reverse_iterator as well:
for (auto RI = L.rbegin(), RE = L.rend(); RI != RE;)
fooThatMightRemoveArgFromList(*RI++);
Converting between iterator and reverse_iterator for the same node uses
the getReverse() function.
reverse_iterator iterator::getReverse();
iterator reverse_iterator::getReverse();
Why doesn't iterator <=> reverse_iterator conversion use constructors?
In order to catch and update old code, reverse_iterator does not even
have an explicit conversion from iterator. It wouldn't be safe because
there would be no reasonable way to catch all the bugs from the changed
semantic (see the changes at call sites that are part of this patch).
Old code used this API:
std::reverse_iterator::reverse_iterator(iterator);
iterator std::reverse_iterator::base();
Here's how to update from old code to new (that incorporates the
semantic change), assuming I is an ilist<>::iterator and RI is an
ilist<>::reverse_iterator:
[Old] ==> [New]
reverse_iterator(I) (--I).getReverse()
reverse_iterator(I) ++I.getReverse()
--reverse_iterator(I) I.getReverse()
reverse_iterator(++I) I.getReverse()
RI.base() (--RI).getReverse()
RI.base() ++RI.getReverse()
--RI.base() RI.getReverse()
(++RI).base() RI.getReverse()
delete &*RI, RE = end() delete &*RI++
RI->erase(), RE = end() RI++->erase()
=======================================
Note: bundle iterators are out of scope
=======================================
MachineBasicBlock::iterator, also known as
MachineInstrBundleIterator<MachineInstr>, is a wrapper to represent
MachineInstr bundles. The idea is that each operator++ takes you to the
beginning of the next bundle. Implementing a sane reverse iterator for
this is harder than ilist. Here are the options:
- Use std::reverse_iterator<MBB::i>. Store a handle to the beginning of
the next bundle. A call to operator*() runs a loop (usually
operator--() will be called 1 time, for unbundled instructions).
Increment/decrement just works. This is the status quo.
- Store a handle to the final node in the bundle. A call to operator*()
still runs a loop, but it iterates one time fewer (usually
operator--() will be called 0 times, for unbundled instructions).
Increment/decrement just works.
- Make the ilist_sentinel<MachineInstr> *always* store that it's the
sentinel (instead of just in asserts mode). Then the bundle iterator
can sniff the sentinel bit in operator++().
I initially tried implementing the end() option as part of this commit,
but updating iterator/reverse_iterator conversion call sites was
error-prone. I have a WIP series of patches that implements the final
option.
llvm-svn: 280032
2016-08-30 02:13:12 +02:00
|
|
|
void transferNodesFromList(SymbolTableListTraits &L2, iterator first,
|
|
|
|
iterator last);
|
|
|
|
// private:
|
2007-04-17 05:26:42 +02:00
|
|
|
template<typename TPtr>
|
|
|
|
void setSymTabObject(TPtr *, TPtr);
|
2009-03-07 13:33:24 +01:00
|
|
|
static ValueSymbolTable *toPtr(ValueSymbolTable *P) { return P; }
|
|
|
|
static ValueSymbolTable *toPtr(ValueSymbolTable &R) { return &R; }
|
2002-06-25 18:12:52 +02:00
|
|
|
};
|
|
|
|
|
2015-10-07 22:05:10 +02:00
|
|
|
/// List that automatically updates parent links and symbol tables.
|
|
|
|
///
|
|
|
|
/// When nodes are inserted into and removed from this list, the associated
|
|
|
|
/// symbol table will be automatically updated. Similarly, parent links get
|
|
|
|
/// updated automatically.
|
2016-09-03 04:07:45 +02:00
|
|
|
template <class T>
|
|
|
|
class SymbolTableList
|
|
|
|
: public iplist_impl<simple_ilist<T>, SymbolTableListTraits<T>> {};
|
2015-10-07 22:05:10 +02:00
|
|
|
|
2017-02-17 01:00:09 +01:00
|
|
|
} // end namespace llvm
|
2003-11-11 23:41:34 +01:00
|
|
|
|
2017-02-17 01:00:09 +01:00
|
|
|
#endif // LLVM_IR_SYMBOLTABLELISTTRAITS_H
|