From fe32eccfec706170aa07dd6ae5fb00883939e23e Mon Sep 17 00:00:00 2001 From: "Duncan P. N. Exon Smith" Date: Sat, 3 Sep 2016 02:07:45 +0000 Subject: [PATCH] ADT: Split out iplist_impl from iplist, NFC Split out iplist_impl from iplist, and change SymbolTableList to inherit directly from iplist_impl. This makes it more straightforward to add new template paramaters to iplist [*]: - iplist_impl takes a "base" list that provides the intrusive functionality (usually simple_ilist) and a traits class. - iplist no longer takes a "Traits" template parameter. It only takes the value_type, T, and instantiates iplist_impl with simple_ilist and ilist_traits. - SymbolTableList now inherits from iplist_impl, instead of iplist. Note for out-of-tree code: if you have an iplist whose second template parameter was *not* the default (i.e., not ilist_traits), you have three options: - Stop using a custom traits class, and instead specialize ilist_traits. This is the usual thing to do. - Specialize iplist to pass your custom traits class into iplist_impl. - Create your own trivial list type that passes your custom traits class into iplist_impl (see SymbolTableList<> for an example). [*]: The eventual goal is to start tracking a sentinel bit on the MachineInstr list even when LLVM_ENABLE_ABI_BREAKING_CHECKS is off, which will enable MachineBasicBlock::reverse_iterator to have normal list invalidation semantics that matching the new iplist<>::reverse_iterator from r280032. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@280569 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ADT/ilist.h | 53 +++++++++++++++++++++------------ include/llvm/IR/SymbolTableListTraits.h | 5 ++-- 2 files changed, 37 insertions(+), 21 deletions(-) diff --git a/include/llvm/ADT/ilist.h b/include/llvm/ADT/ilist.h index 62b7246af8a..ce5af68d7a7 100644 --- a/include/llvm/ADT/ilist.h +++ b/include/llvm/ADT/ilist.h @@ -145,14 +145,21 @@ template struct HasObsoleteCustomization { //===----------------------------------------------------------------------===// // -/// The subset of list functionality that can safely be used on nodes of +/// A wrapper around an intrusive list with callbacks and non-intrusive +/// ownership. +/// +/// This wraps a purely intrusive list (like simple_ilist) with a configurable +/// traits class. The traits can implement callbacks and customize the +/// ownership semantics. +/// +/// This is a subset of ilist functionality that can safely be used on nodes of /// polymorphic types, i.e. a heterogeneous list with a common base class that /// holds the next/prev pointers. The only state of the list itself is an /// ilist_sentinel, which holds pointers to the first and last nodes in the /// list. -template > -class iplist : public Traits, simple_ilist { - typedef simple_ilist base_list_type; +template +class iplist_impl : public TraitsT, IntrusiveListT { + typedef IntrusiveListT base_list_type; public: typedef typename base_list_type::pointer pointer; @@ -172,19 +179,20 @@ private: // TODO: Drop this assertion and the transitive type traits anytime after // v4.0 is branched (i.e,. keep them for one release to help out-of-tree code // update). - static_assert(!ilist_detail::HasObsoleteCustomization::value, - "ilist customization points have changed!"); + static_assert( + !ilist_detail::HasObsoleteCustomization::value, + "ilist customization points have changed!"); static bool op_less(const_reference L, const_reference R) { return L < R; } static bool op_equal(const_reference L, const_reference R) { return L == R; } // Copying intrusively linked nodes doesn't make sense. - iplist(const iplist &) = delete; - void operator=(const iplist &) = delete; + iplist_impl(const iplist_impl &) = delete; + void operator=(const iplist_impl &) = delete; public: - iplist() = default; - ~iplist() { clear(); } + iplist_impl() = default; + ~iplist_impl() { clear(); } // Miscellaneous inspection routines. size_type max_size() const { return size_type(-1); } @@ -197,7 +205,7 @@ public: using base_list_type::front; using base_list_type::back; - void swap(iplist &RHS) { + void swap(iplist_impl &RHS) { assert(0 && "Swap does not use list traits callback correctly yet!"); base_list_type::swap(RHS); } @@ -253,7 +261,7 @@ private: // transfer - The heart of the splice function. Move linked list nodes from // [first, last) into position. // - void transfer(iterator position, iplist &L2, iterator first, iterator last) { + void transfer(iterator position, iplist_impl &L2, iterator first, iterator last) { if (position == last) return; @@ -297,33 +305,33 @@ public: } // Splice members - defined in terms of transfer... - void splice(iterator where, iplist &L2) { + void splice(iterator where, iplist_impl &L2) { if (!L2.empty()) transfer(where, L2, L2.begin(), L2.end()); } - void splice(iterator where, iplist &L2, iterator first) { + void splice(iterator where, iplist_impl &L2, iterator first) { iterator last = first; ++last; if (where == first || where == last) return; // No change transfer(where, L2, first, last); } - void splice(iterator where, iplist &L2, iterator first, iterator last) { + void splice(iterator where, iplist_impl &L2, iterator first, iterator last) { if (first != last) transfer(where, L2, first, last); } - void splice(iterator where, iplist &L2, reference N) { + void splice(iterator where, iplist_impl &L2, reference N) { splice(where, L2, iterator(N)); } - void splice(iterator where, iplist &L2, pointer N) { + void splice(iterator where, iplist_impl &L2, pointer N) { splice(where, L2, iterator(N)); } template - void merge(iplist &Right, Compare comp) { + void merge(iplist_impl &Right, Compare comp) { if (this == &Right) return; this->transferNodesFromList(Right, Right.begin(), Right.end()); base_list_type::merge(Right, comp); } - void merge(iplist &Right) { return merge(Right, op_less); } + void merge(iplist_impl &Right) { return merge(Right, op_less); } using base_list_type::sort; @@ -352,6 +360,13 @@ public: } }; +/// An intrusive list with ownership and callbacks specified/controlled by +/// ilist_traits, only with API safe for polymorphic types. +template +class iplist : public iplist_impl, ilist_traits> {}; + +/// An intrusive list with ownership and callbacks specified/controlled by +/// ilist_traits, with API that is unsafe for polymorphic types. template class ilist : public iplist { typedef iplist base_list_type; diff --git a/include/llvm/IR/SymbolTableListTraits.h b/include/llvm/IR/SymbolTableListTraits.h index 713985f51d5..5c6d58affd7 100644 --- a/include/llvm/IR/SymbolTableListTraits.h +++ b/include/llvm/IR/SymbolTableListTraits.h @@ -105,8 +105,9 @@ public: /// 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 -class SymbolTableList : public iplist> {}; +template +class SymbolTableList + : public iplist_impl, SymbolTableListTraits> {}; } // End llvm namespace -- 2.11.0