llvm.org GIT mirror llvm / 3e97be2
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@278513 91177308-0d34-0410-b5e6-96231b3b80d8 Duncan P. N. Exon Smith 3 years ago
10 changed file(s) with 54 addition(s) and 139 deletion(s). Raw diff Collapse all Expand all
244244 };
245245
246246 template
247 struct ilist_traits >
248 : public ilist_default_traits > {
249 typedef SparseBitVectorElement Element;
250
251 Element *createSentinel() const { return static_cast(&Sentinel); }
252 static void destroySentinel(Element *) {}
253
254 Element *provideInitialHead() const { return createSentinel(); }
255 Element *ensureHead(Element *) const { return createSentinel(); }
256 static void noteHead(Element *, Element *) {}
257
258 private:
259 mutable ilist_half_node Sentinel;
260 };
247 struct ilist_sentinel_traits>
248 : public ilist_half_embedded_sentinel_traits<
249 SparseBitVectorElement> {};
261250
262251 template
263252 class SparseBitVector {
108108 template class ilist_node;
109109
110110 /// Traits with an embedded ilist_node as a sentinel.
111 ///
112 /// FIXME: The downcast in createSentinel() is UB.
113111 template struct ilist_embedded_sentinel_traits {
114112 /// Get hold of the node that marks the end of the list.
113 ///
114 /// FIXME: This downcast is UB. See llvm.org/PR26753.
115 LLVM_NO_SANITIZE("object-size")
115116 NodeTy *createSentinel() const {
116117 // Since i(p)lists always publicly derive from their corresponding traits,
117118 // placing a data member in this class will augment the i(p)list. But since
133134 };
134135
135136 /// Trait with an embedded ilist_half_node as a sentinel.
136 ///
137 /// FIXME: The downcast in createSentinel() is UB.
138137 template struct ilist_half_embedded_sentinel_traits {
139138 /// Get hold of the node that marks the end of the list.
139 ///
140 /// FIXME: This downcast is UB. See llvm.org/PR26753.
141 LLVM_NO_SANITIZE("object-size")
140142 NodeTy *createSentinel() const {
141143 // See comment in ilist_embedded_sentinel_traits::createSentinel().
142144 return static_cast(&Sentinel);
149151
150152 private:
151153 mutable ilist_half_node Sentinel;
154 };
155
156 /// Traits with an embedded full node as a sentinel.
157 template struct ilist_full_embedded_sentinel_traits {
158 /// Get hold of the node that marks the end of the list.
159 NodeTy *createSentinel() const { return &Sentinel; }
160 static void destroySentinel(NodeTy *) {}
161
162 NodeTy *provideInitialHead() const { return createSentinel(); }
163 NodeTy *ensureHead(NodeTy *) const { return createSentinel(); }
164 static void noteHead(NodeTy *, NodeTy *) {}
165
166 private:
167 mutable NodeTy Sentinel;
152168 };
153169
154170 /// ilist_node_traits - A fragment for template traits for intrusive list
9090 void deleted() override;
9191 };
9292
93 template<> struct ilist_traits
94 : public ilist_default_traits {
95 // createSentinel is used to get hold of a node that marks the end of
96 // the list...
97 // The sentinel is relative to this instance, so we use a non-static
98 // method.
99 IVStrideUse *createSentinel() const {
100 // since i(p)lists always publicly derive from the corresponding
101 // traits, placing a data member in this class will augment i(p)list.
102 // But since the NodeTy is expected to publicly derive from
103 // ilist_node, there is a legal viable downcast from it
104 // to NodeTy. We use this trick to superpose i(p)list with a "ghostly"
105 // NodeTy, which becomes the sentinel. Dereferencing the sentinel is
106 // forbidden (save the ilist_node) so no one will ever notice
107 // the superposition.
108 return static_cast(&Sentinel);
109 }
110 static void destroySentinel(IVStrideUse*) {}
111
112 IVStrideUse *provideInitialHead() const { return createSentinel(); }
113 IVStrideUse *ensureHead(IVStrideUse*) const { return createSentinel(); }
114 static void noteHead(IVStrideUse*, IVStrideUse*) {}
115
116 private:
117 mutable ilist_node Sentinel;
118 };
93 template <>
94 struct ilist_sentinel_traits
95 : public ilist_embedded_sentinel_traits {};
11996
12097 class IVUsers {
12198 friend class IVStrideUse;
3838 typedef unsigned LaneBitmask;
3939
4040 template <>
41 struct ilist_sentinel_traits
42 : public ilist_half_embedded_sentinel_traits {};
43
44 template <>
4145 struct ilist_traits : public ilist_default_traits {
4246 private:
43 mutable ilist_half_node Sentinel;
44
4547 // this is only set by the MachineBasicBlock owning the LiveList
4648 friend class MachineBasicBlock;
4749 MachineBasicBlock* Parent;
4850
4951 public:
50 MachineInstr *createSentinel() const {
51 return static_cast(&Sentinel);
52 }
53 void destroySentinel(MachineInstr *) const {}
54
55 MachineInstr *provideInitialHead() const { return createSentinel(); }
56 MachineInstr *ensureHead(MachineInstr*) const { return createSentinel(); }
57 static void noteHead(MachineInstr*, MachineInstr*) {}
58
5952 void addNodeToList(MachineInstr* N);
6053 void removeNodeFromList(MachineInstr* N);
6154 void transferNodesFromList(ilist_traits &SrcTraits,
4848 struct WinEHFuncInfo;
4949
5050 template <>
51 struct ilist_sentinel_traits
52 : public ilist_half_embedded_sentinel_traits {};
53
54 template <>
5155 struct ilist_traits
5256 : public ilist_default_traits {
53 mutable ilist_half_node Sentinel;
54 public:
55 // FIXME: This downcast is UB. See llvm.org/PR26753.
56 LLVM_NO_SANITIZE("object-size")
57 MachineBasicBlock *createSentinel() const {
58 return static_cast(&Sentinel);
59 }
60 void destroySentinel(MachineBasicBlock *) const {}
61
62 MachineBasicBlock *provideInitialHead() const { return createSentinel(); }
63 MachineBasicBlock *ensureHead(MachineBasicBlock*) const {
64 return createSentinel();
65 }
66 static void noteHead(MachineBasicBlock*, MachineBasicBlock*) {}
67
6857 void addNodeToList(MachineBasicBlock* MBB);
6958 void removeNodeFromList(MachineBasicBlock* MBB);
7059 void deleteNode(MachineBasicBlock *MBB);
8080 }
8181 };
8282
83 template<> struct ilist_traits : public ilist_default_traits {
84 private:
85 mutable ilist_half_node Sentinel;
86 public:
87 SDNode *createSentinel() const {
88 return static_cast(&Sentinel);
89 }
90 static void destroySentinel(SDNode *) {}
91
92 SDNode *provideInitialHead() const { return createSentinel(); }
93 SDNode *ensureHead(SDNode*) const { return createSentinel(); }
94 static void noteHead(SDNode*, SDNode*) {}
95
83 template <>
84 struct ilist_sentinel_traits
85 : public ilist_half_embedded_sentinel_traits {};
86
87 template <> struct ilist_traits : public ilist_default_traits {
9688 static void deleteNode(SDNode *) {
9789 llvm_unreachable("ilist_traits shouldn't see a deleteNode call!");
9890 }
6868 };
6969
7070 template <>
71 struct ilist_traits : public ilist_default_traits {
72 private:
73 mutable ilist_half_node Sentinel;
74 public:
75 IndexListEntry *createSentinel() const {
76 return static_cast(&Sentinel);
77 }
78 void destroySentinel(IndexListEntry *) const {}
79
80 IndexListEntry *provideInitialHead() const { return createSentinel(); }
81 IndexListEntry *ensureHead(IndexListEntry*) const { return createSentinel(); }
82 static void noteHead(IndexListEntry*, IndexListEntry*) {}
71 struct ilist_sentinel_traits
72 : public ilist_half_embedded_sentinel_traits {};
73
74 template <>
75 struct ilist_traits
76 : public ilist_default_traits {
8377 void deleteNode(IndexListEntry *N) {}
8478
8579 private:
3636 class StructType;
3737 template class SmallPtrSetImpl;
3838
39 template <>
40 struct ilist_sentinel_traits
41 : public ilist_embedded_sentinel_traits {};
42
3943 template<> struct ilist_traits
4044 : public ilist_default_traits {
41 // createSentinel is used to get hold of a node that marks the end of
42 // the list...
43 NamedMDNode *createSentinel() const {
44 return static_cast(&Sentinel);
45 }
46 static void destroySentinel(NamedMDNode*) {}
47
48 NamedMDNode *provideInitialHead() const { return createSentinel(); }
49 NamedMDNode *ensureHead(NamedMDNode*) const { return createSentinel(); }
50 static void noteHead(NamedMDNode*, NamedMDNode*) {}
5145 void addNodeToList(NamedMDNode *) {}
5246 void removeNodeFromList(NamedMDNode *) {}
53
54 private:
55 mutable ilist_node Sentinel;
5647 };
5748
5849 /// A Module instance is used to store all the information related to an
170170 };
171171
172172 template <>
173 struct ilist_traits : public ilist_default_traits {
174 /// See details of the instruction class for why this trick works
175 // FIXME: This downcast is UB. See llvm.org/PR26753.
176 LLVM_NO_SANITIZE("object-size")
177 MemoryAccess *createSentinel() const {
178 return static_cast(&Sentinel);
179 }
180
181 static void destroySentinel(MemoryAccess *) {}
182
183 MemoryAccess *provideInitialHead() const { return createSentinel(); }
184 MemoryAccess *ensureHead(MemoryAccess *) const { return createSentinel(); }
185 static void noteHead(MemoryAccess *, MemoryAccess *) {}
186
187 private:
188 mutable ilist_half_node Sentinel;
189 };
173 struct ilist_sentinel_traits
174 : public ilist_half_embedded_sentinel_traits {};
190175
191176 inline raw_ostream &operator<<(raw_ostream &OS, const MemoryAccess &MA) {
192177 MA.print(OS);
148148 }
149149
150150 namespace llvm {
151 template<>
152 struct ilist_sentinel_traits {
153 Token *createSentinel() const {
154 return &Sentinel;
155 }
156 static void destroySentinel(Token*) {}
157
158 Token *provideInitialHead() const { return createSentinel(); }
159 Token *ensureHead(Token*) const { return createSentinel(); }
160 static void noteHead(Token*, Token*) {}
161
162 private:
163 mutable Token Sentinel;
164 };
151 template <>
152 struct ilist_sentinel_traits
153 : public ilist_full_embedded_sentinel_traits {};
165154
166155 template<>
167156 struct ilist_node_traits {