[llvm] r278513 - ADT: Share code for embedded sentinel traits, NFC

Duncan P. N. Exon Smith via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 12 08:00:55 PDT 2016


Author: dexonsmith
Date: Fri Aug 12 10:00:55 2016
New Revision: 278513

URL: http://llvm.org/viewvc/llvm-project?rev=278513&view=rev
Log:
ADT: Share code for embedded sentinel traits, NFC

Share code for the (mostly problematic) embedded sentinel traits.
- Move the LLVM_NO_SANITIZE("object-size") attribute to
  ilist_half_embedded_sentinel_traits and ilist_embedded_sentinel_traits
  (previously it spread throughout the code duplication).
- Add an ilist_full_embedded_sentinel_traits which has no UB (but has
  the downside of storing the complete node).
- Replace all the custom sentinel traits in LLVM with a declaration of
  ilist_sentinel_traits that inherits from one of the embedded sentinel
  traits classes.

There are still custom sentinel traits in other LLVM subprojects.  I'll
remove those in a follow-up.

Nothing at all should be changing here, this is just rearranging code.
Note that the final goal here is to remove the sentinel traits
altogether, settling on the memory layout of
ilist_half_embedded_sentinel_traits without the UB.  This intermediate
step moves the logic into ilist.h.

Modified:
    llvm/trunk/include/llvm/ADT/SparseBitVector.h
    llvm/trunk/include/llvm/ADT/ilist.h
    llvm/trunk/include/llvm/Analysis/IVUsers.h
    llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h
    llvm/trunk/include/llvm/CodeGen/MachineFunction.h
    llvm/trunk/include/llvm/CodeGen/SelectionDAG.h
    llvm/trunk/include/llvm/CodeGen/SlotIndexes.h
    llvm/trunk/include/llvm/IR/Module.h
    llvm/trunk/include/llvm/Transforms/Utils/MemorySSA.h
    llvm/trunk/lib/Support/YAMLParser.cpp

Modified: llvm/trunk/include/llvm/ADT/SparseBitVector.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/SparseBitVector.h?rev=278513&r1=278512&r2=278513&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/SparseBitVector.h (original)
+++ llvm/trunk/include/llvm/ADT/SparseBitVector.h Fri Aug 12 10:00:55 2016
@@ -245,20 +245,9 @@ public:
 };
 
 template <unsigned ElementSize>
-struct ilist_traits<SparseBitVectorElement<ElementSize> >
-  : public ilist_default_traits<SparseBitVectorElement<ElementSize> > {
-  typedef SparseBitVectorElement<ElementSize> Element;
-
-  Element *createSentinel() const { return static_cast<Element *>(&Sentinel); }
-  static void destroySentinel(Element *) {}
-
-  Element *provideInitialHead() const { return createSentinel(); }
-  Element *ensureHead(Element *) const { return createSentinel(); }
-  static void noteHead(Element *, Element *) {}
-
-private:
-  mutable ilist_half_node<Element> Sentinel;
-};
+struct ilist_sentinel_traits<SparseBitVectorElement<ElementSize>>
+    : public ilist_half_embedded_sentinel_traits<
+          SparseBitVectorElement<ElementSize>> {};
 
 template <unsigned ElementSize = 128>
 class SparseBitVector {

Modified: llvm/trunk/include/llvm/ADT/ilist.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/ilist.h?rev=278513&r1=278512&r2=278513&view=diff
==============================================================================
--- llvm/trunk/include/llvm/ADT/ilist.h (original)
+++ llvm/trunk/include/llvm/ADT/ilist.h Fri Aug 12 10:00:55 2016
@@ -109,10 +109,11 @@ template <typename NodeTy> class ilist_h
 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.
+  ///
+  /// FIXME: This downcast is UB.  See llvm.org/PR26753.
+  LLVM_NO_SANITIZE("object-size")
   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
@@ -134,10 +135,11 @@ private:
 };
 
 /// 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.
+  ///
+  /// FIXME: This downcast is UB.  See llvm.org/PR26753.
+  LLVM_NO_SANITIZE("object-size")
   NodeTy *createSentinel() const {
     // See comment in ilist_embedded_sentinel_traits::createSentinel().
     return static_cast<NodeTy *>(&Sentinel);
@@ -152,6 +154,20 @@ private:
   mutable ilist_half_node<NodeTy> Sentinel;
 };
 
+/// Traits with an embedded full node as a sentinel.
+template <typename NodeTy> struct ilist_full_embedded_sentinel_traits {
+  /// Get hold of the node that marks the end of the list.
+  NodeTy *createSentinel() const { return &Sentinel; }
+  static void destroySentinel(NodeTy *) {}
+
+  NodeTy *provideInitialHead() const { return createSentinel(); }
+  NodeTy *ensureHead(NodeTy *) const { return createSentinel(); }
+  static void noteHead(NodeTy *, NodeTy *) {}
+
+private:
+  mutable NodeTy Sentinel;
+};
+
 /// ilist_node_traits - A fragment for template traits for intrusive list
 /// that provides default node related operations.
 ///

Modified: llvm/trunk/include/llvm/Analysis/IVUsers.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/IVUsers.h?rev=278513&r1=278512&r2=278513&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/IVUsers.h (original)
+++ llvm/trunk/include/llvm/Analysis/IVUsers.h Fri Aug 12 10:00:55 2016
@@ -91,32 +91,9 @@ private:
   void deleted() override;
 };
 
-template<> struct ilist_traits<IVStrideUse>
-  : public ilist_default_traits<IVStrideUse> {
-  // createSentinel is used to get hold of a node that marks the end of
-  // the list...
-  // The sentinel is relative to this instance, so we use a non-static
-  // method.
-  IVStrideUse *createSentinel() const {
-    // since i(p)lists always publicly derive from the corresponding
-    // traits, placing a data member in this class will augment i(p)list.
-    // But since the NodeTy is expected to publicly derive from
-    // ilist_node<NodeTy>, there is a legal viable downcast from it
-    // to NodeTy. We use this trick to superpose 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<IVStrideUse*>(&Sentinel);
-  }
-  static void destroySentinel(IVStrideUse*) {}
-
-  IVStrideUse *provideInitialHead() const { return createSentinel(); }
-  IVStrideUse *ensureHead(IVStrideUse*) const { return createSentinel(); }
-  static void noteHead(IVStrideUse*, IVStrideUse*) {}
-
-private:
-  mutable ilist_node<IVStrideUse> Sentinel;
-};
+template <>
+struct ilist_sentinel_traits<IVStrideUse>
+    : public ilist_embedded_sentinel_traits<IVStrideUse> {};
 
 class IVUsers {
   friend class IVStrideUse;

Modified: llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h?rev=278513&r1=278512&r2=278513&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineBasicBlock.h Fri Aug 12 10:00:55 2016
@@ -39,24 +39,17 @@ class MachineBranchProbabilityInfo;
 typedef unsigned LaneBitmask;
 
 template <>
+struct ilist_sentinel_traits<MachineInstr>
+    : public ilist_half_embedded_sentinel_traits<MachineInstr> {};
+
+template <>
 struct ilist_traits<MachineInstr> : public ilist_default_traits<MachineInstr> {
 private:
-  mutable ilist_half_node<MachineInstr> Sentinel;
-
   // this is only set by the MachineBasicBlock owning the LiveList
   friend class MachineBasicBlock;
   MachineBasicBlock* Parent;
 
 public:
-  MachineInstr *createSentinel() const {
-    return static_cast<MachineInstr*>(&Sentinel);
-  }
-  void destroySentinel(MachineInstr *) const {}
-
-  MachineInstr *provideInitialHead() const { return createSentinel(); }
-  MachineInstr *ensureHead(MachineInstr*) const { return createSentinel(); }
-  static void noteHead(MachineInstr*, MachineInstr*) {}
-
   void addNodeToList(MachineInstr* N);
   void removeNodeFromList(MachineInstr* N);
   void transferNodesFromList(ilist_traits &SrcTraits,

Modified: llvm/trunk/include/llvm/CodeGen/MachineFunction.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/MachineFunction.h?rev=278513&r1=278512&r2=278513&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/MachineFunction.h (original)
+++ llvm/trunk/include/llvm/CodeGen/MachineFunction.h Fri Aug 12 10:00:55 2016
@@ -49,23 +49,12 @@ struct MachinePointerInfo;
 struct WinEHFuncInfo;
 
 template <>
+struct ilist_sentinel_traits<MachineBasicBlock>
+    : public ilist_half_embedded_sentinel_traits<MachineBasicBlock> {};
+
+template <>
 struct ilist_traits<MachineBasicBlock>
     : public ilist_default_traits<MachineBasicBlock> {
-  mutable ilist_half_node<MachineBasicBlock> Sentinel;
-public:
-  // FIXME: This downcast is UB. See llvm.org/PR26753.
-  LLVM_NO_SANITIZE("object-size")
-  MachineBasicBlock *createSentinel() const {
-    return static_cast<MachineBasicBlock*>(&Sentinel);
-  }
-  void destroySentinel(MachineBasicBlock *) const {}
-
-  MachineBasicBlock *provideInitialHead() const { return createSentinel(); }
-  MachineBasicBlock *ensureHead(MachineBasicBlock*) const {
-    return createSentinel();
-  }
-  static void noteHead(MachineBasicBlock*, MachineBasicBlock*) {}
-
   void addNodeToList(MachineBasicBlock* MBB);
   void removeNodeFromList(MachineBasicBlock* MBB);
   void deleteNode(MachineBasicBlock *MBB);

Modified: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SelectionDAG.h?rev=278513&r1=278512&r2=278513&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h Fri Aug 12 10:00:55 2016
@@ -81,19 +81,11 @@ template<> struct FoldingSetTrait<SDVTLi
   }
 };
 
-template<> struct ilist_traits<SDNode> : public ilist_default_traits<SDNode> {
-private:
-  mutable ilist_half_node<SDNode> Sentinel;
-public:
-  SDNode *createSentinel() const {
-    return static_cast<SDNode*>(&Sentinel);
-  }
-  static void destroySentinel(SDNode *) {}
-
-  SDNode *provideInitialHead() const { return createSentinel(); }
-  SDNode *ensureHead(SDNode*) const { return createSentinel(); }
-  static void noteHead(SDNode*, SDNode*) {}
+template <>
+struct ilist_sentinel_traits<SDNode>
+    : public ilist_half_embedded_sentinel_traits<SDNode> {};
 
+template <> struct ilist_traits<SDNode> : public ilist_default_traits<SDNode> {
   static void deleteNode(SDNode *) {
     llvm_unreachable("ilist_traits<SDNode> shouldn't see a deleteNode call!");
   }

Modified: llvm/trunk/include/llvm/CodeGen/SlotIndexes.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/SlotIndexes.h?rev=278513&r1=278512&r2=278513&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/SlotIndexes.h (original)
+++ llvm/trunk/include/llvm/CodeGen/SlotIndexes.h Fri Aug 12 10:00:55 2016
@@ -69,18 +69,12 @@ namespace llvm {
   };
 
   template <>
-  struct ilist_traits<IndexListEntry> : public ilist_default_traits<IndexListEntry> {
-  private:
-    mutable ilist_half_node<IndexListEntry> Sentinel;
-  public:
-    IndexListEntry *createSentinel() const {
-      return static_cast<IndexListEntry*>(&Sentinel);
-    }
-    void destroySentinel(IndexListEntry *) const {}
+  struct ilist_sentinel_traits<IndexListEntry>
+      : public ilist_half_embedded_sentinel_traits<IndexListEntry> {};
 
-    IndexListEntry *provideInitialHead() const { return createSentinel(); }
-    IndexListEntry *ensureHead(IndexListEntry*) const { return createSentinel(); }
-    static void noteHead(IndexListEntry*, IndexListEntry*) {}
+  template <>
+  struct ilist_traits<IndexListEntry>
+      : public ilist_default_traits<IndexListEntry> {
     void deleteNode(IndexListEntry *N) {}
 
   private:

Modified: llvm/trunk/include/llvm/IR/Module.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Module.h?rev=278513&r1=278512&r2=278513&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Module.h (original)
+++ llvm/trunk/include/llvm/IR/Module.h Fri Aug 12 10:00:55 2016
@@ -37,23 +37,14 @@ class RandomNumberGenerator;
 class StructType;
 template <class PtrType> class SmallPtrSetImpl;
 
+template <>
+struct ilist_sentinel_traits<NamedMDNode>
+    : public ilist_embedded_sentinel_traits<NamedMDNode> {};
+
 template<> struct ilist_traits<NamedMDNode>
   : public ilist_default_traits<NamedMDNode> {
-  // createSentinel is used to get hold of a node that marks the end of
-  // the list...
-  NamedMDNode *createSentinel() const {
-    return static_cast<NamedMDNode*>(&Sentinel);
-  }
-  static void destroySentinel(NamedMDNode*) {}
-
-  NamedMDNode *provideInitialHead() const { return createSentinel(); }
-  NamedMDNode *ensureHead(NamedMDNode*) const { return createSentinel(); }
-  static void noteHead(NamedMDNode*, NamedMDNode*) {}
   void addNodeToList(NamedMDNode *) {}
   void removeNodeFromList(NamedMDNode *) {}
-
-private:
-  mutable ilist_node<NamedMDNode> Sentinel;
 };
 
 /// A Module instance is used to store all the information related to an

Modified: llvm/trunk/include/llvm/Transforms/Utils/MemorySSA.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Transforms/Utils/MemorySSA.h?rev=278513&r1=278512&r2=278513&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Transforms/Utils/MemorySSA.h (original)
+++ llvm/trunk/include/llvm/Transforms/Utils/MemorySSA.h Fri Aug 12 10:00:55 2016
@@ -171,23 +171,8 @@ private:
 };
 
 template <>
-struct ilist_traits<MemoryAccess> : public ilist_default_traits<MemoryAccess> {
-  /// See details of the instruction class for why this trick works
-  // FIXME: This downcast is UB. See llvm.org/PR26753.
-  LLVM_NO_SANITIZE("object-size")
-  MemoryAccess *createSentinel() const {
-    return static_cast<MemoryAccess *>(&Sentinel);
-  }
-
-  static void destroySentinel(MemoryAccess *) {}
-
-  MemoryAccess *provideInitialHead() const { return createSentinel(); }
-  MemoryAccess *ensureHead(MemoryAccess *) const { return createSentinel(); }
-  static void noteHead(MemoryAccess *, MemoryAccess *) {}
-
-private:
-  mutable ilist_half_node<MemoryAccess> Sentinel;
-};
+struct ilist_sentinel_traits<MemoryAccess>
+    : public ilist_half_embedded_sentinel_traits<MemoryAccess> {};
 
 inline raw_ostream &operator<<(raw_ostream &OS, const MemoryAccess &MA) {
   MA.print(OS);

Modified: llvm/trunk/lib/Support/YAMLParser.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/YAMLParser.cpp?rev=278513&r1=278512&r2=278513&view=diff
==============================================================================
--- llvm/trunk/lib/Support/YAMLParser.cpp (original)
+++ llvm/trunk/lib/Support/YAMLParser.cpp Fri Aug 12 10:00:55 2016
@@ -149,20 +149,9 @@ struct Token : ilist_node<Token> {
 }
 
 namespace llvm {
-template<>
-struct ilist_sentinel_traits<Token> {
-  Token *createSentinel() const {
-    return &Sentinel;
-  }
-  static void destroySentinel(Token*) {}
-
-  Token *provideInitialHead() const { return createSentinel(); }
-  Token *ensureHead(Token*) const { return createSentinel(); }
-  static void noteHead(Token*, Token*) {}
-
-private:
-  mutable Token Sentinel;
-};
+template <>
+struct ilist_sentinel_traits<Token>
+    : public ilist_full_embedded_sentinel_traits<Token> {};
 
 template<>
 struct ilist_node_traits<Token> {




More information about the llvm-commits mailing list