[llvm] r249602 - IR: Create SymbolTableList wrapper around iplist, NFC

Duncan P. N. Exon Smith via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 7 13:05:10 PDT 2015


Author: dexonsmith
Date: Wed Oct  7 15:05:10 2015
New Revision: 249602

URL: http://llvm.org/viewvc/llvm-project?rev=249602&view=rev
Log:
IR: Create SymbolTableList wrapper around iplist, NFC

Create `SymbolTableList`, a wrapper around `iplist` for lists that
automatically manage a symbol table.  This commit reduces a ton of code
duplication between the six traits classes that were used previously.

As a drive by, reduce the number of template parameters from 2 to 1 by
using a SymbolTableListParentType metafunction (I originally had this as
a separate commit, but it touched most of the same lines so I squashed
them).

I'm in the process of trying to remove the UB in `createSentinel()` (see
the FIXMEs I added for `ilist_embedded_sentinel_traits` and
`ilist_half_embedded_sentinel_traits`).  My eventual goal is to separate
the list logic into a base class layer that knows nothing about (and
isn't templated on) the downcasted nodes -- removing the need to invoke
UB -- but for now I'm just trying to get a handle on all the current use
cases (and cleaning things up as I see them).

Besides these six SymbolTable lists, there are two others that use the
addNode/removeNode/transferNodes() hooks: the `MachineInstruction` and
`MachineBasicBlock` lists.  Ideally there'll be a way to factor these
hooks out of the low-level API entirely, but I'm not quite there yet.

Modified:
    llvm/trunk/include/llvm/ADT/ilist.h
    llvm/trunk/include/llvm/ADT/ilist_node.h
    llvm/trunk/include/llvm/IR/Argument.h
    llvm/trunk/include/llvm/IR/BasicBlock.h
    llvm/trunk/include/llvm/IR/Function.h
    llvm/trunk/include/llvm/IR/GlobalAlias.h
    llvm/trunk/include/llvm/IR/GlobalVariable.h
    llvm/trunk/include/llvm/IR/InstIterator.h
    llvm/trunk/include/llvm/IR/Instruction.h
    llvm/trunk/include/llvm/IR/Metadata.h
    llvm/trunk/include/llvm/IR/Module.h
    llvm/trunk/include/llvm/IR/SymbolTableListTraits.h
    llvm/trunk/include/llvm/IR/ValueSymbolTable.h
    llvm/trunk/lib/IR/BasicBlock.cpp
    llvm/trunk/lib/IR/Function.cpp
    llvm/trunk/lib/IR/Module.cpp
    llvm/trunk/lib/IR/SymbolTableListTraitsImpl.h

Modified: llvm/trunk/include/llvm/ADT/ilist.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ilist.h?rev=249602&r1=249601&r2=249602&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/ilist.h (original)
+++ llvm/trunk/include/llvm/ADT/ilist.h Wed Oct  7 15:05:10 2015
@@ -104,6 +104,53 @@ struct ilist_sentinel_traits {
   }
 };
 
+template <typename NodeTy> class ilist_half_node;
+template <typename NodeTy> class ilist_node;
+
+/// Traits with an embedded ilist_node as a sentinel.
+///
+/// FIXME: The downcast in createSentinel() is UB.
+template <typename NodeTy> struct ilist_embedded_sentinel_traits {
+  /// Get hold of the node that marks the end of the list.
+  NodeTy *createSentinel() const {
+    // Since i(p)lists always publicly derive from their corresponding traits,
+    // placing a data member in this class will augment the i(p)list.  But since
+    // the NodeTy is expected to be publicly derive from ilist_node<NodeTy>,
+    // there is a legal viable downcast from it to NodeTy. We use this trick to
+    // superimpose an i(p)list with a "ghostly" NodeTy, which becomes the
+    // sentinel. Dereferencing the sentinel is forbidden (save the
+    // ilist_node<NodeTy>), so no one will ever notice the superposition.
+    return static_cast<NodeTy *>(&Sentinel);
+  }
+  static void destroySentinel(NodeTy *) {}
+
+  NodeTy *provideInitialHead() const { return createSentinel(); }
+  NodeTy *ensureHead(NodeTy *) const { return createSentinel(); }
+  static void noteHead(NodeTy *, NodeTy *) {}
+
+private:
+  mutable ilist_node<NodeTy> Sentinel;
+};
+
+/// Trait with an embedded ilist_half_node as a sentinel.
+///
+/// FIXME: The downcast in createSentinel() is UB.
+template <typename NodeTy> struct ilist_half_embedded_sentinel_traits {
+  /// Get hold of the node that marks the end of the list.
+  NodeTy *createSentinel() const {
+    // See comment in ilist_embedded_sentinel_traits::createSentinel().
+    return static_cast<NodeTy *>(&Sentinel);
+  }
+  static void destroySentinel(NodeTy *) {}
+
+  NodeTy *provideInitialHead() const { return createSentinel(); }
+  NodeTy *ensureHead(NodeTy *) const { return createSentinel(); }
+  static void noteHead(NodeTy *, NodeTy *) {}
+
+private:
+  mutable ilist_half_node<NodeTy> Sentinel;
+};
+
 /// ilist_node_traits - A fragment for template traits for intrusive list
 /// that provides default node related operations.
 ///

Modified: llvm/trunk/include/llvm/ADT/ilist_node.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ilist_node.h?rev=249602&r1=249601&r2=249602&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/ilist_node.h (original)
+++ llvm/trunk/include/llvm/ADT/ilist_node.h Wed Oct  7 15:05:10 2015
@@ -19,12 +19,15 @@ namespace llvm {
 
 template<typename NodeTy>
 struct ilist_traits;
+template <typename NodeTy> struct ilist_embedded_sentinel_traits;
+template <typename NodeTy> struct ilist_half_embedded_sentinel_traits;
 
 /// ilist_half_node - Base class that provides prev services for sentinels.
 ///
 template<typename NodeTy>
 class ilist_half_node {
   friend struct ilist_traits<NodeTy>;
+  friend struct ilist_half_embedded_sentinel_traits<NodeTy>;
   NodeTy *Prev;
 protected:
   NodeTy *getPrev() { return Prev; }
@@ -43,6 +46,8 @@ template<typename NodeTy>
 class ilist_node : private ilist_half_node<NodeTy> {
   friend struct ilist_nextprev_traits<NodeTy>;
   friend struct ilist_traits<NodeTy>;
+  friend struct ilist_half_embedded_sentinel_traits<NodeTy>;
+  friend struct ilist_embedded_sentinel_traits<NodeTy>;
   NodeTy *Next;
   NodeTy *getNext() { return Next; }
   const NodeTy *getNext() const { return Next; }

Modified: llvm/trunk/include/llvm/IR/Argument.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Argument.h?rev=249602&r1=249601&r2=249602&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Argument.h (original)
+++ llvm/trunk/include/llvm/IR/Argument.h Wed Oct  7 15:05:10 2015
@@ -21,8 +21,7 @@
 
 namespace llvm {
 
-template<typename ValueSubClass, typename ItemParentClass>
-  class SymbolTableListTraits;
+template <typename NodeTy> class SymbolTableListTraits;
 
 /// \brief LLVM Argument representation
 ///
@@ -36,7 +35,7 @@ class Argument : public Value, public il
   virtual void anchor();
   Function *Parent;
 
-  friend class SymbolTableListTraits<Argument, Function>;
+  friend class SymbolTableListTraits<Argument>;
   void setParent(Function *parent);
 
 public:

Modified: llvm/trunk/include/llvm/IR/BasicBlock.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/BasicBlock.h?rev=249602&r1=249601&r2=249602&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/BasicBlock.h (original)
+++ llvm/trunk/include/llvm/IR/BasicBlock.h Wed Oct  7 15:05:10 2015
@@ -30,20 +30,9 @@ class LLVMContext;
 class BlockAddress;
 class Function;
 
-// Traits for intrusive list of basic blocks...
-template<> struct ilist_traits<BasicBlock>
-  : public SymbolTableListTraits<BasicBlock, Function> {
-
-  BasicBlock *createSentinel() const;
-  static void destroySentinel(BasicBlock*) {}
-
-  BasicBlock *provideInitialHead() const { return createSentinel(); }
-  BasicBlock *ensureHead(BasicBlock*) const { return createSentinel(); }
-  static void noteHead(BasicBlock*, BasicBlock*) {}
-private:
-  mutable ilist_half_node<BasicBlock> Sentinel;
-};
-
+template <>
+struct SymbolTableListSentinelTraits<BasicBlock>
+    : public ilist_half_embedded_sentinel_traits<BasicBlock> {};
 
 /// \brief LLVM Basic Block Representation
 ///
@@ -64,13 +53,14 @@ class BasicBlock : public Value, // Basi
                    public ilist_node<BasicBlock> {
   friend class BlockAddress;
 public:
-  typedef iplist<Instruction> InstListType;
+  typedef SymbolTableList<Instruction> InstListType;
+
 private:
   InstListType InstList;
   Function *Parent;
 
   void setParent(Function *parent);
-  friend class SymbolTableListTraits<BasicBlock, Function>;
+  friend class SymbolTableListTraits<BasicBlock>;
 
   BasicBlock(const BasicBlock &) = delete;
   void operator=(const BasicBlock &) = delete;
@@ -169,7 +159,7 @@ public:
   /// \brief Unlink 'this' from the containing function and delete it.
   ///
   // \returns an iterator pointing to the element after the erased one.
-  iplist<BasicBlock>::iterator eraseFromParent();
+  SymbolTableList<BasicBlock>::iterator eraseFromParent();
 
   /// \brief Unlink this basic block from its current function and insert it
   /// into the function that \p MovePos lives in, right before \p MovePos.
@@ -340,12 +330,6 @@ private:
   }
 };
 
-// createSentinel is used to get hold of the node that marks the end of the
-// list... (same trick used here as in ilist_traits<Instruction>)
-inline BasicBlock *ilist_traits<BasicBlock>::createSentinel() const {
-    return static_cast<BasicBlock*>(&Sentinel);
-}
-
 // Create wrappers for C Binding types (see CBindingWrapping.h).
 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(BasicBlock, LLVMBasicBlockRef)
 

Modified: llvm/trunk/include/llvm/IR/Function.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Function.h?rev=249602&r1=249601&r2=249602&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Function.h (original)
+++ llvm/trunk/include/llvm/IR/Function.h Wed Oct  7 15:05:10 2015
@@ -34,26 +34,14 @@ class FunctionType;
 class LLVMContext;
 class DISubprogram;
 
-template<> struct ilist_traits<Argument>
-  : public SymbolTableListTraits<Argument, Function> {
-
-  Argument *createSentinel() const {
-    return static_cast<Argument*>(&Sentinel);
-  }
-  static void destroySentinel(Argument*) {}
-
-  Argument *provideInitialHead() const { return createSentinel(); }
-  Argument *ensureHead(Argument*) const { return createSentinel(); }
-  static void noteHead(Argument*, Argument*) {}
-
-private:
-  mutable ilist_half_node<Argument> Sentinel;
-};
+template <>
+struct SymbolTableListSentinelTraits<Argument>
+    : public ilist_half_embedded_sentinel_traits<Argument> {};
 
 class Function : public GlobalObject, public ilist_node<Function> {
 public:
-  typedef iplist<Argument> ArgumentListType;
-  typedef iplist<BasicBlock> BasicBlockListType;
+  typedef SymbolTableList<Argument> ArgumentListType;
+  typedef SymbolTableList<BasicBlock> BasicBlockListType;
 
   // BasicBlock iterators...
   typedef BasicBlockListType::iterator iterator;
@@ -90,7 +78,7 @@ private:
                                 (Value ? Mask : 0u));
   }
 
-  friend class SymbolTableListTraits<Function, Module>;
+  friend class SymbolTableListTraits<Function>;
 
   void setParent(Module *parent);
 

Modified: llvm/trunk/include/llvm/IR/GlobalAlias.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/GlobalAlias.h?rev=249602&r1=249601&r2=249602&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/GlobalAlias.h (original)
+++ llvm/trunk/include/llvm/IR/GlobalAlias.h Wed Oct  7 15:05:10 2015
@@ -23,11 +23,10 @@
 namespace llvm {
 
 class Module;
-template<typename ValueSubClass, typename ItemParentClass>
-  class SymbolTableListTraits;
+template <typename ValueSubClass> class SymbolTableListTraits;
 
 class GlobalAlias : public GlobalValue, public ilist_node<GlobalAlias> {
-  friend class SymbolTableListTraits<GlobalAlias, Module>;
+  friend class SymbolTableListTraits<GlobalAlias>;
   void operator=(const GlobalAlias &) = delete;
   GlobalAlias(const GlobalAlias &) = delete;
 

Modified: llvm/trunk/include/llvm/IR/GlobalVariable.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/GlobalVariable.h?rev=249602&r1=249601&r2=249602&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/GlobalVariable.h (original)
+++ llvm/trunk/include/llvm/IR/GlobalVariable.h Wed Oct  7 15:05:10 2015
@@ -29,11 +29,10 @@ namespace llvm {
 
 class Module;
 class Constant;
-template<typename ValueSubClass, typename ItemParentClass>
-  class SymbolTableListTraits;
+template <typename ValueSubClass> class SymbolTableListTraits;
 
 class GlobalVariable : public GlobalObject, public ilist_node<GlobalVariable> {
-  friend class SymbolTableListTraits<GlobalVariable, Module>;
+  friend class SymbolTableListTraits<GlobalVariable>;
   void *operator new(size_t, unsigned) = delete;
   void operator=(const GlobalVariable &) = delete;
   GlobalVariable(const GlobalVariable &) = delete;

Modified: llvm/trunk/include/llvm/IR/InstIterator.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/InstIterator.h?rev=249602&r1=249601&r2=249602&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/InstIterator.h (original)
+++ llvm/trunk/include/llvm/IR/InstIterator.h Wed Oct  7 15:05:10 2015
@@ -115,13 +115,10 @@ private:
   }
 };
 
-
-typedef InstIterator<iplist<BasicBlock>,
-                     Function::iterator, BasicBlock::iterator,
-                     Instruction> inst_iterator;
-typedef InstIterator<const iplist<BasicBlock>,
-                     Function::const_iterator,
-                     BasicBlock::const_iterator,
+typedef InstIterator<SymbolTableList<BasicBlock>, Function::iterator,
+                     BasicBlock::iterator, Instruction> inst_iterator;
+typedef InstIterator<const SymbolTableList<BasicBlock>,
+                     Function::const_iterator, BasicBlock::const_iterator,
                      const Instruction> const_inst_iterator;
 typedef iterator_range<inst_iterator> inst_range;
 typedef iterator_range<const_inst_iterator> const_inst_range;

Modified: llvm/trunk/include/llvm/IR/Instruction.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Instruction.h?rev=249602&r1=249601&r2=249602&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Instruction.h (original)
+++ llvm/trunk/include/llvm/IR/Instruction.h Wed Oct  7 15:05:10 2015
@@ -30,23 +30,8 @@ class BasicBlock;
 struct AAMDNodes;
 
 template <>
-struct ilist_traits<Instruction>
-    : public SymbolTableListTraits<Instruction, BasicBlock> {
-
-  /// \brief Return a node that marks the end of a list.
-  ///
-  /// The sentinel is relative to this instance, so we use a non-static
-  /// method.
-  Instruction *createSentinel() const;
-  static void destroySentinel(Instruction *) {}
-
-  Instruction *provideInitialHead() const { return createSentinel(); }
-  Instruction *ensureHead(Instruction *) const { return createSentinel(); }
-  static void noteHead(Instruction *, Instruction *) {}
-
-private:
-  mutable ilist_half_node<Instruction> Sentinel;
-};
+struct SymbolTableListSentinelTraits<Instruction>
+    : public ilist_half_embedded_sentinel_traits<Instruction> {};
 
 class Instruction : public User, public ilist_node<Instruction> {
   void operator=(const Instruction &) = delete;
@@ -89,7 +74,7 @@ public:
   /// block and deletes it.
   ///
   /// \returns an iterator pointing to the element after the erased one
-  iplist<Instruction>::iterator eraseFromParent();
+  SymbolTableList<Instruction>::iterator eraseFromParent();
 
   /// Insert an unlinked instruction into a basic block immediately before
   /// the specified instruction.
@@ -506,7 +491,7 @@ private:
                          (V ? HasMetadataBit : 0));
   }
 
-  friend class SymbolTableListTraits<Instruction, BasicBlock>;
+  friend class SymbolTableListTraits<Instruction>;
   void setParent(BasicBlock *P);
 protected:
   // Instruction subclasses can stick up to 15 bits of stuff into the
@@ -532,17 +517,6 @@ private:
   Instruction *cloneImpl() const;
 };
 
-inline Instruction *ilist_traits<Instruction>::createSentinel() const {
-  // Since i(p)lists always publicly derive from their corresponding traits,
-  // placing a data member in this class will augment the i(p)list.  But since
-  // the NodeTy is expected to be publicly derive from ilist_node<NodeTy>,
-  // there is a legal viable downcast from it to NodeTy. We use this trick to
-  // superimpose an i(p)list with a "ghostly" NodeTy, which becomes the
-  // sentinel. Dereferencing the sentinel is forbidden (save the
-  // ilist_node<NodeTy>), so no one will ever notice the superposition.
-  return static_cast<Instruction *>(&Sentinel);
-}
-
 // Instruction* is only 4-byte aligned.
 template<>
 class PointerLikeTypeTraits<Instruction*> {

Modified: llvm/trunk/include/llvm/IR/Metadata.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Metadata.h?rev=249602&r1=249601&r2=249602&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Metadata.h (original)
+++ llvm/trunk/include/llvm/IR/Metadata.h Wed Oct  7 15:05:10 2015
@@ -32,9 +32,6 @@ class LLVMContext;
 class Module;
 class ModuleSlotTracker;
 
-template<typename ValueSubClass, typename ItemParentClass>
-  class SymbolTableListTraits;
-
 enum LLVMConstants : uint32_t {
   DEBUG_METADATA_VERSION = 3 // Current debug info version number.
 };
@@ -1129,7 +1126,6 @@ public:
 ///
 /// TODO: Inherit from Metadata.
 class NamedMDNode : public ilist_node<NamedMDNode> {
-  friend class SymbolTableListTraits<NamedMDNode, Module>;
   friend struct ilist_traits<NamedMDNode>;
   friend class LLVMContextImpl;
   friend class Module;

Modified: llvm/trunk/include/llvm/IR/Module.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Module.h?rev=249602&r1=249601&r2=249602&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Module.h (original)
+++ llvm/trunk/include/llvm/IR/Module.h Wed Oct  7 15:05:10 2015
@@ -34,58 +34,6 @@ class LLVMContext;
 class RandomNumberGenerator;
 class StructType;
 
-template<> struct ilist_traits<Function>
-  : public SymbolTableListTraits<Function, Module> {
-
-  // createSentinel is used to get hold of the node that marks the end of the
-  // list... (same trick used here as in ilist_traits<Instruction>)
-  Function *createSentinel() const {
-    return static_cast<Function*>(&Sentinel);
-  }
-  static void destroySentinel(Function*) {}
-
-  Function *provideInitialHead() const { return createSentinel(); }
-  Function *ensureHead(Function*) const { return createSentinel(); }
-  static void noteHead(Function*, Function*) {}
-
-private:
-  mutable ilist_node<Function> Sentinel;
-};
-
-template<> struct ilist_traits<GlobalVariable>
-  : public SymbolTableListTraits<GlobalVariable, Module> {
-  // createSentinel is used to create a node that marks the end of the list.
-  GlobalVariable *createSentinel() const {
-    return static_cast<GlobalVariable*>(&Sentinel);
-  }
-  static void destroySentinel(GlobalVariable*) {}
-
-  GlobalVariable *provideInitialHead() const { return createSentinel(); }
-  GlobalVariable *ensureHead(GlobalVariable *) const {
-    return createSentinel();
-  }
-  static void noteHead(GlobalVariable *, GlobalVariable *) {}
-
-private:
-  mutable ilist_node<GlobalVariable> Sentinel;
-};
-
-template<> struct ilist_traits<GlobalAlias>
-  : public SymbolTableListTraits<GlobalAlias, Module> {
-  // createSentinel is used to create a node that marks the end of the list.
-  GlobalAlias *createSentinel() const {
-    return static_cast<GlobalAlias*>(&Sentinel);
-  }
-  static void destroySentinel(GlobalAlias*) {}
-
-  GlobalAlias *provideInitialHead() const { return createSentinel(); }
-  GlobalAlias *ensureHead(GlobalAlias *) const { return createSentinel(); }
-  static void noteHead(GlobalAlias *, GlobalAlias *) {}
-
-private:
-  mutable ilist_node<GlobalAlias> Sentinel;
-};
-
 template<> struct ilist_traits<NamedMDNode>
   : public ilist_default_traits<NamedMDNode> {
   // createSentinel is used to get hold of a node that marks the end of
@@ -121,11 +69,11 @@ class Module {
 /// @{
 public:
   /// The type for the list of global variables.
-  typedef iplist<GlobalVariable> GlobalListType;
+  typedef SymbolTableList<GlobalVariable> GlobalListType;
   /// The type for the list of functions.
-  typedef iplist<Function> FunctionListType;
+  typedef SymbolTableList<Function> FunctionListType;
   /// The type for the list of aliases.
-  typedef iplist<GlobalAlias> AliasListType;
+  typedef SymbolTableList<GlobalAlias> AliasListType;
   /// The type for the list of named metadata.
   typedef ilist<NamedMDNode> NamedMDListType;
   /// The type of the comdat "symbol" table.

Modified: llvm/trunk/include/llvm/IR/SymbolTableListTraits.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/SymbolTableListTraits.h?rev=249602&r1=249601&r2=249602&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/SymbolTableListTraits.h (original)
+++ llvm/trunk/include/llvm/IR/SymbolTableListTraits.h Wed Oct  7 15:05:10 2015
@@ -34,11 +34,46 @@ template <typename NodeTy> class ilist_i
 template <typename NodeTy, typename Traits> class iplist;
 template <typename Ty> struct ilist_traits;
 
+template <typename NodeTy>
+struct SymbolTableListSentinelTraits
+    : public ilist_embedded_sentinel_traits<NodeTy> {};
+
+/// 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 {};
+class Argument;
+class BasicBlock;
+class Function;
+class Instruction;
+class GlobalVariable;
+class GlobalAlias;
+class Module;
+#define DEFINE_SYMBOL_TABLE_PARENT_TYPE(NODE, PARENT)                          \
+  template <> struct SymbolTableListParentType<NODE> { typedef PARENT type; };
+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)
+#undef DEFINE_SYMBOL_TABLE_PARENT_TYPE
+
+template <typename NodeTy> class SymbolTableList;
+
 // ValueSubClass   - The type of objects that I hold, e.g. Instruction.
 // ItemParentClass - The type of object that owns the list, e.g. BasicBlock.
 //
-template<typename ValueSubClass, typename ItemParentClass>
-class SymbolTableListTraits : public ilist_default_traits<ValueSubClass> {
+template <typename ValueSubClass>
+class SymbolTableListTraits
+    : public ilist_nextprev_traits<ValueSubClass>,
+      public SymbolTableListSentinelTraits<ValueSubClass>,
+      public ilist_node_traits<ValueSubClass> {
+  typedef SymbolTableList<ValueSubClass> ListTy;
+  typedef
+      typename SymbolTableListParentType<ValueSubClass>::type ItemParentClass;
+
 public:
   SymbolTableListTraits() {}
 
@@ -48,12 +83,12 @@ private:
   ItemParentClass *getListOwner() {
     size_t Offset(size_t(&((ItemParentClass*)nullptr->*ItemParentClass::
                            getSublistAccess(static_cast<ValueSubClass*>(nullptr)))));
-    iplist<ValueSubClass>* Anchor(static_cast<iplist<ValueSubClass>*>(this));
+    ListTy *Anchor(static_cast<ListTy *>(this));
     return reinterpret_cast<ItemParentClass*>(reinterpret_cast<char*>(Anchor)-
                                               Offset);
   }
 
-  static iplist<ValueSubClass> &getList(ItemParentClass *Par) {
+  static ListTy &getList(ItemParentClass *Par) {
     return Par->*(Par->getSublistAccess((ValueSubClass*)nullptr));
   }
 
@@ -64,7 +99,7 @@ private:
 public:
   void addNodeToList(ValueSubClass *V);
   void removeNodeFromList(ValueSubClass *V);
-  void transferNodesFromList(ilist_traits<ValueSubClass> &L2,
+  void transferNodesFromList(SymbolTableListTraits &L2,
                              ilist_iterator<ValueSubClass> first,
                              ilist_iterator<ValueSubClass> last);
 //private:
@@ -74,6 +109,14 @@ public:
   static ValueSymbolTable *toPtr(ValueSymbolTable &R) { return &R; }
 };
 
+/// 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.
+template <typename NodeTy>
+class SymbolTableList : public iplist<NodeTy, SymbolTableListTraits<NodeTy>> {};
+
 } // End llvm namespace
 
 #endif

Modified: llvm/trunk/include/llvm/IR/ValueSymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/ValueSymbolTable.h?rev=249602&r1=249601&r2=249602&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/ValueSymbolTable.h (original)
+++ llvm/trunk/include/llvm/IR/ValueSymbolTable.h Wed Oct  7 15:05:10 2015
@@ -19,8 +19,7 @@
 #include "llvm/Support/DataTypes.h"
 
 namespace llvm {
-  template<typename ValueSubClass, typename ItemParentClass>
-        class SymbolTableListTraits;
+  template <typename ValueSubClass> class SymbolTableListTraits;
   class BasicBlock;
   class Function;
   class NamedMDNode;
@@ -33,12 +32,12 @@ namespace llvm {
 ///
 class ValueSymbolTable {
   friend class Value;
-  friend class SymbolTableListTraits<Argument, Function>;
-  friend class SymbolTableListTraits<BasicBlock, Function>;
-  friend class SymbolTableListTraits<Instruction, BasicBlock>;
-  friend class SymbolTableListTraits<Function, Module>;
-  friend class SymbolTableListTraits<GlobalVariable, Module>;
-  friend class SymbolTableListTraits<GlobalAlias, Module>;
+  friend class SymbolTableListTraits<Argument>;
+  friend class SymbolTableListTraits<BasicBlock>;
+  friend class SymbolTableListTraits<Instruction>;
+  friend class SymbolTableListTraits<Function>;
+  friend class SymbolTableListTraits<GlobalVariable>;
+  friend class SymbolTableListTraits<GlobalAlias>;
 /// @name Types
 /// @{
 public:

Modified: llvm/trunk/lib/IR/BasicBlock.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/BasicBlock.cpp?rev=249602&r1=249601&r2=249602&view=diff
==============================================================================
--- llvm/trunk/lib/IR/BasicBlock.cpp (original)
+++ llvm/trunk/lib/IR/BasicBlock.cpp Wed Oct  7 15:05:10 2015
@@ -36,7 +36,7 @@ LLVMContext &BasicBlock::getContext() co
 
 // Explicit instantiation of SymbolTableListTraits since some of the methods
 // are not in the public header file...
-template class llvm::SymbolTableListTraits<Instruction, BasicBlock>;
+template class llvm::SymbolTableListTraits<Instruction>;
 
 BasicBlock::BasicBlock(LLVMContext &C, const Twine &Name, Function *NewParent,
                        BasicBlock *InsertBefore)

Modified: llvm/trunk/lib/IR/Function.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Function.cpp?rev=249602&r1=249601&r2=249602&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Function.cpp (original)
+++ llvm/trunk/lib/IR/Function.cpp Wed Oct  7 15:05:10 2015
@@ -35,8 +35,8 @@ using namespace llvm;
 
 // Explicit instantiations of SymbolTableListTraits since some of the methods
 // are not in the public header file...
-template class llvm::SymbolTableListTraits<Argument, Function>;
-template class llvm::SymbolTableListTraits<BasicBlock, Function>;
+template class llvm::SymbolTableListTraits<Argument>;
+template class llvm::SymbolTableListTraits<BasicBlock>;
 
 //===----------------------------------------------------------------------===//
 // Argument Implementation

Modified: llvm/trunk/lib/IR/Module.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Module.cpp?rev=249602&r1=249601&r2=249602&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Module.cpp (original)
+++ llvm/trunk/lib/IR/Module.cpp Wed Oct  7 15:05:10 2015
@@ -38,9 +38,9 @@ using namespace llvm;
 
 // Explicit instantiations of SymbolTableListTraits since some of the methods
 // are not in the public header file.
-template class llvm::SymbolTableListTraits<Function, Module>;
-template class llvm::SymbolTableListTraits<GlobalVariable, Module>;
-template class llvm::SymbolTableListTraits<GlobalAlias, Module>;
+template class llvm::SymbolTableListTraits<Function>;
+template class llvm::SymbolTableListTraits<GlobalVariable>;
+template class llvm::SymbolTableListTraits<GlobalAlias>;
 
 //===----------------------------------------------------------------------===//
 // Primitive Module methods.

Modified: llvm/trunk/lib/IR/SymbolTableListTraitsImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/SymbolTableListTraitsImpl.h?rev=249602&r1=249601&r2=249602&view=diff
==============================================================================
--- llvm/trunk/lib/IR/SymbolTableListTraitsImpl.h (original)
+++ llvm/trunk/lib/IR/SymbolTableListTraitsImpl.h Wed Oct  7 15:05:10 2015
@@ -24,10 +24,10 @@ namespace llvm {
 /// setSymTabObject - This is called when (f.e.) the parent of a basic block
 /// changes.  This requires us to remove all the instruction symtab entries from
 /// the current function and reinsert them into the new function.
-template<typename ValueSubClass, typename ItemParentClass>
-template<typename TPtr>
-void SymbolTableListTraits<ValueSubClass,ItemParentClass>
-::setSymTabObject(TPtr *Dest, TPtr Src) {
+template <typename ValueSubClass>
+template <typename TPtr>
+void SymbolTableListTraits<ValueSubClass>::setSymTabObject(TPtr *Dest,
+                                                           TPtr Src) {
   // Get the old symtab and value list before doing the assignment.
   ValueSymbolTable *OldST = getSymTab(getListOwner());
 
@@ -41,7 +41,7 @@ void SymbolTableListTraits<ValueSubClass
   if (OldST == NewST) return;
   
   // Move all the elements from the old symtab to the new one.
-  iplist<ValueSubClass> &ItemList = getList(getListOwner());
+  ListTy &ItemList = getList(getListOwner());
   if (ItemList.empty()) return;
   
   if (OldST) {
@@ -60,9 +60,8 @@ void SymbolTableListTraits<ValueSubClass
   
 }
 
-template<typename ValueSubClass, typename ItemParentClass>
-void SymbolTableListTraits<ValueSubClass,ItemParentClass>
-::addNodeToList(ValueSubClass *V) {
+template <typename ValueSubClass>
+void SymbolTableListTraits<ValueSubClass>::addNodeToList(ValueSubClass *V) {
   assert(!V->getParent() && "Value already in a container!!");
   ItemParentClass *Owner = getListOwner();
   V->setParent(Owner);
@@ -71,20 +70,19 @@ void SymbolTableListTraits<ValueSubClass
       ST->reinsertValue(V);
 }
 
-template<typename ValueSubClass, typename ItemParentClass>
-void SymbolTableListTraits<ValueSubClass,ItemParentClass>
-::removeNodeFromList(ValueSubClass *V) {
+template <typename ValueSubClass>
+void SymbolTableListTraits<ValueSubClass>::removeNodeFromList(
+    ValueSubClass *V) {
   V->setParent(nullptr);
   if (V->hasName())
     if (ValueSymbolTable *ST = getSymTab(getListOwner()))
       ST->removeValueName(V->getValueName());
 }
 
-template<typename ValueSubClass, typename ItemParentClass>
-void SymbolTableListTraits<ValueSubClass,ItemParentClass>
-::transferNodesFromList(ilist_traits<ValueSubClass> &L2,
-                        ilist_iterator<ValueSubClass> first,
-                        ilist_iterator<ValueSubClass> last) {
+template <typename ValueSubClass>
+void SymbolTableListTraits<ValueSubClass>::transferNodesFromList(
+    SymbolTableListTraits &L2, ilist_iterator<ValueSubClass> first,
+    ilist_iterator<ValueSubClass> last) {
   // We only have to do work here if transferring instructions between BBs
   ItemParentClass *NewIP = getListOwner(), *OldIP = L2.getListOwner();
   if (NewIP == OldIP) return;  // No work to do at all...




More information about the llvm-commits mailing list