OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_COMPILER_GENERIC_NODE_H_ | 5 #ifndef V8_COMPILER_GENERIC_NODE_H_ |
6 #define V8_COMPILER_GENERIC_NODE_H_ | 6 #define V8_COMPILER_GENERIC_NODE_H_ |
7 | 7 |
8 #include "src/v8.h" | 8 #include "src/v8.h" |
9 | 9 |
10 #include "src/zone-containers.h" | 10 #include "src/zone-containers.h" |
11 | 11 |
12 namespace v8 { | 12 namespace v8 { |
13 namespace internal { | 13 namespace internal { |
14 namespace compiler { | 14 namespace compiler { |
15 | 15 |
16 class GenericGraphBase; | 16 class GenericGraphBase; |
| 17 template <class N> |
| 18 class GenericEdge; |
17 | 19 |
18 typedef int NodeId; | 20 typedef int NodeId; |
19 | 21 |
20 // A GenericNode<> is the basic primitive of graphs. GenericNode's are | 22 // A GenericNode<> is the basic primitive of graphs. GenericNode's are |
21 // chained together by input/use chains but by default otherwise contain only an | 23 // chained together by input/use chains but by default otherwise contain only an |
22 // identifying number which specific applications of graphs and nodes can use | 24 // identifying number which specific applications of graphs and nodes can use |
23 // to index auxiliary out-of-line data, especially transient data. | 25 // to index auxiliary out-of-line data, especially transient data. |
24 // Specializations of the templatized GenericNode<> class must provide a base | 26 // Specializations of the templatized GenericNode<> class must provide a base |
25 // class B that contains all of the members to be made available in each | 27 // class B that contains all of the members to be made available in each |
26 // specialized Node instance. GenericNode uses a mixin template pattern to | 28 // specialized Node instance. GenericNode uses a mixin template pattern to |
(...skipping 25 matching lines...) Expand all Loading... |
52 } | 54 } |
53 return static_cast<S*>(current->from); | 55 return static_cast<S*>(current->from); |
54 } | 56 } |
55 inline void ReplaceUses(GenericNode* replace_to); | 57 inline void ReplaceUses(GenericNode* replace_to); |
56 template <class UnaryPredicate> | 58 template <class UnaryPredicate> |
57 inline void ReplaceUsesIf(UnaryPredicate pred, GenericNode* replace_to); | 59 inline void ReplaceUsesIf(UnaryPredicate pred, GenericNode* replace_to); |
58 inline void RemoveAllInputs(); | 60 inline void RemoveAllInputs(); |
59 | 61 |
60 inline void TrimInputCount(int input_count); | 62 inline void TrimInputCount(int input_count); |
61 | 63 |
| 64 class InputEdges { |
| 65 public: |
| 66 class iterator; |
| 67 iterator begin(); |
| 68 iterator end(); |
| 69 bool empty() { return begin() == end(); } |
| 70 |
| 71 explicit InputEdges(GenericNode* node) : node_(node) {} |
| 72 |
| 73 private: |
| 74 GenericNode* node_; |
| 75 }; |
| 76 |
62 class Inputs { | 77 class Inputs { |
63 public: | 78 public: |
64 class iterator; | 79 class iterator; |
65 iterator begin(); | 80 iterator begin(); |
66 iterator end(); | 81 iterator end(); |
| 82 bool empty() { return begin() == end(); } |
67 | 83 |
68 explicit Inputs(GenericNode* node) : node_(node) {} | 84 explicit Inputs(GenericNode* node) : node_(node) {} |
69 | 85 |
70 private: | 86 private: |
71 GenericNode* node_; | 87 GenericNode* node_; |
72 }; | 88 }; |
73 | 89 |
| 90 InputEdges input_edges() { return InputEdges(this); } |
74 Inputs inputs() { return Inputs(this); } | 91 Inputs inputs() { return Inputs(this); } |
75 | 92 |
| 93 class UseEdges { |
| 94 public: |
| 95 class iterator; |
| 96 iterator begin(); |
| 97 iterator end(); |
| 98 bool empty() { return begin() == end(); } |
| 99 |
| 100 explicit UseEdges(GenericNode* node) : node_(node) {} |
| 101 |
| 102 private: |
| 103 GenericNode* node_; |
| 104 }; |
| 105 |
76 class Uses { | 106 class Uses { |
77 public: | 107 public: |
78 class iterator; | 108 class iterator; |
79 iterator begin(); | 109 iterator begin(); |
80 iterator end(); | 110 iterator end(); |
81 bool empty() { return begin() == end(); } | 111 bool empty() { return begin() == end(); } |
82 | 112 |
83 explicit Uses(GenericNode* node) : node_(node) {} | 113 explicit Uses(GenericNode* node) : node_(node) {} |
84 | 114 |
85 private: | 115 private: |
86 GenericNode* node_; | 116 GenericNode* node_; |
87 }; | 117 }; |
88 | 118 |
89 Uses uses() { return Uses(this); } | 119 Uses uses() { return Uses(this); } |
90 | 120 UseEdges use_edges() { return UseEdges(this); } |
91 class Edge; | |
92 | 121 |
93 bool OwnedBy(GenericNode* owner) const; | 122 bool OwnedBy(GenericNode* owner) const; |
94 | 123 |
95 static S* New(GenericGraphBase* graph, int input_count, S** inputs, | 124 static S* New(GenericGraphBase* graph, int input_count, S** inputs, |
96 bool has_extensible_inputs); | 125 bool has_extensible_inputs); |
97 | 126 |
98 protected: | 127 protected: |
99 friend class GenericGraphBase; | 128 friend class GenericGraphBase; |
| 129 friend class GenericEdge<S>; |
100 | 130 |
101 class Use : public ZoneObject { | 131 class Use : public ZoneObject { |
102 public: | 132 public: |
103 GenericNode* from; | 133 GenericNode* from; |
104 Use* next; | 134 Use* next; |
105 Use* prev; | 135 Use* prev; |
106 int input_index; | 136 int input_index; |
107 }; | 137 }; |
108 | 138 |
109 class Input { | 139 class Input { |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
155 } inputs_; | 185 } inputs_; |
156 int use_count_; | 186 int use_count_; |
157 Use* first_use_; | 187 Use* first_use_; |
158 Use* last_use_; | 188 Use* last_use_; |
159 | 189 |
160 DISALLOW_COPY_AND_ASSIGN(GenericNode); | 190 DISALLOW_COPY_AND_ASSIGN(GenericNode); |
161 }; | 191 }; |
162 | 192 |
163 // An encapsulation for information associated with a single use of node as a | 193 // An encapsulation for information associated with a single use of node as a |
164 // input from another node, allowing access to both the defining node and | 194 // input from another node, allowing access to both the defining node and |
165 // the ndoe having the input. | 195 // the node having the input. |
166 template <class B, class S> | 196 template <class N> |
167 class GenericNode<B, S>::Edge { | 197 class GenericEdge { |
168 public: | 198 public: |
169 S* from() const { return static_cast<S*>(input_->use->from); } | 199 GenericEdge(const GenericEdge& other) : input_(other.input_) {} |
170 S* to() const { return static_cast<S*>(input_->to); } | 200 GenericEdge() : input_(NULL) {} |
| 201 |
| 202 N* from() const { return static_cast<N*>(input_->use->from); } |
| 203 N* to() const { return static_cast<N*>(input_->to); } |
171 int index() const { | 204 int index() const { |
172 int index = input_->use->input_index; | 205 int index = input_->use->input_index; |
173 DCHECK(index < input_->use->from->input_count_); | 206 DCHECK(index < input_->use->from->input_count_); |
174 return index; | 207 return index; |
175 } | 208 } |
176 | 209 bool operator==(const GenericEdge& other) { return input_ == other.input_; } |
177 private: | 210 bool operator!=(const GenericEdge& other) { return !(*this == other); } |
178 friend class GenericNode<B, S>::Uses::iterator; | 211 |
179 friend class GenericNode<B, S>::Inputs::iterator; | 212 explicit GenericEdge(typename N::Input* input) : input_(input) {} |
180 | 213 |
181 explicit Edge(typename GenericNode<B, S>::Input* input) : input_(input) {} | 214 void UpdateTo(N* new_to) { input_->Update(new_to); } |
182 | 215 |
183 typename GenericNode<B, S>::Input* input_; | 216 private: |
184 }; | 217 typename N::Input* input_; |
| 218 }; |
| 219 |
185 | 220 |
186 // A forward iterator to visit the nodes which are depended upon by a node | 221 // A forward iterator to visit the nodes which are depended upon by a node |
187 // in the order of input. | 222 // in the order of input. |
188 template <class B, class S> | 223 template <class B, class S> |
| 224 class GenericNode<B, S>::InputEdges::iterator { |
| 225 public: |
| 226 typedef std::forward_iterator_tag iterator_category; |
| 227 typedef int difference_type; |
| 228 typedef GenericEdge<S> value_type; |
| 229 typedef GenericEdge<S>* pointer; |
| 230 typedef GenericEdge<S>& reference; |
| 231 iterator( |
| 232 const typename GenericNode<B, S>::InputEdges::iterator& other) // NOLINT |
| 233 : input_(other.input_) {} |
| 234 iterator() : input_(NULL) {} |
| 235 |
| 236 GenericEdge<S> operator*() const { return GenericEdge<S>(input_); } |
| 237 bool operator==(const iterator& other) const { return Equals(other); } |
| 238 bool operator!=(const iterator& other) const { return !Equals(other); } |
| 239 iterator& operator++() { |
| 240 DCHECK(input_ != NULL); |
| 241 GenericEdge<S> edge(input_); |
| 242 GenericNode<B, S>* from = edge.from(); |
| 243 SetInput(from, input_->use->input_index + 1); |
| 244 return *this; |
| 245 } |
| 246 iterator& operator++(int) { |
| 247 iterator result(*this); |
| 248 ++(*this); |
| 249 return result; |
| 250 } |
| 251 |
| 252 private: |
| 253 friend class GenericNode; |
| 254 |
| 255 iterator(GenericNode* from, int index = 0) : input_(NULL) { |
| 256 SetInput(from, index); |
| 257 } |
| 258 |
| 259 bool Equals(const iterator& other) const { return other.input_ == input_; } |
| 260 void SetInput(GenericNode* from, int index) { |
| 261 DCHECK(index >= 0 && index <= from->InputCount()); |
| 262 if (index < from->InputCount()) { |
| 263 input_ = from->GetInputRecordPtr(index); |
| 264 } else { |
| 265 input_ = NULL; |
| 266 } |
| 267 } |
| 268 |
| 269 Input* input_; |
| 270 }; |
| 271 |
| 272 |
| 273 template <class B, class S> |
189 class GenericNode<B, S>::Inputs::iterator { | 274 class GenericNode<B, S>::Inputs::iterator { |
190 public: | 275 public: |
| 276 typedef std::forward_iterator_tag iterator_category; |
| 277 typedef int difference_type; |
| 278 typedef S value_type; |
| 279 typedef S* pointer; |
| 280 typedef S& reference; |
191 iterator(const typename GenericNode<B, S>::Inputs::iterator& other) // NOLINT | 281 iterator(const typename GenericNode<B, S>::Inputs::iterator& other) // NOLINT |
192 : node_(other.node_), | 282 : iter_(other.iter_) {} |
193 index_(other.index_) {} | 283 iterator() {} |
194 | 284 |
195 S* operator*() { return static_cast<S*>(GetInput()->to); } | 285 S* operator*() const { return (*iter_).to(); } |
196 typename GenericNode<B, S>::Edge edge() { | 286 bool operator==(const iterator& other) const { return Equals(other); } |
197 return typename GenericNode::Edge(GetInput()); | 287 bool operator!=(const iterator& other) const { return !Equals(other); } |
198 } | 288 iterator& operator++() { |
199 bool operator==(const iterator& other) const { | 289 ++iter_; |
200 return other.index_ == index_ && other.node_ == node_; | 290 return *this; |
201 } | 291 } |
202 bool operator!=(const iterator& other) const { return !(other == *this); } | 292 iterator& operator++(int) { |
203 iterator& operator++() { | 293 iterator result(*this); |
204 DCHECK(node_ != NULL); | 294 ++(*this); |
205 DCHECK(index_ < node_->input_count_); | 295 return result; |
206 ++index_; | 296 } |
207 return *this; | 297 |
208 } | 298 private: |
209 iterator& UpdateToAndIncrement(GenericNode<B, S>* new_to) { | 299 friend class GenericNode<B, S>::Inputs; |
210 typename GenericNode<B, S>::Input* input = GetInput(); | 300 |
211 input->Update(new_to); | 301 iterator(GenericNode* from, int index = 0) : iter_(from, index) {} |
212 index_++; | 302 |
213 return *this; | 303 bool Equals(const iterator& other) const { return other.iter_ == iter_; } |
214 } | 304 |
215 int index() { return index_; } | 305 typename GenericNode<B, S>::InputEdges::iterator iter_; |
216 | 306 }; |
217 private: | 307 |
218 friend class GenericNode; | |
219 | |
220 explicit iterator(GenericNode* node, int index) | |
221 : node_(node), index_(index) {} | |
222 | |
223 Input* GetInput() const { return node_->GetInputRecordPtr(index_); } | |
224 | |
225 GenericNode* node_; | |
226 int index_; | |
227 }; | |
228 | 308 |
229 // A forward iterator to visit the uses of a node. The uses are returned in | 309 // A forward iterator to visit the uses of a node. The uses are returned in |
230 // the order in which they were added as inputs. | 310 // the order in which they were added as inputs. |
231 template <class B, class S> | 311 template <class B, class S> |
| 312 class GenericNode<B, S>::UseEdges::iterator { |
| 313 public: |
| 314 iterator( |
| 315 const typename GenericNode<B, S>::UseEdges::iterator& other) // NOLINT |
| 316 : current_(other.current_), |
| 317 next_(other.next_), |
| 318 index_(other.index_) {} |
| 319 |
| 320 GenericEdge<S> operator*() const { return GenericEdge<S>(CurrentInput()); } |
| 321 |
| 322 bool operator==(const iterator& other) { return Equals(other); } |
| 323 bool operator!=(const iterator& other) { return !Equals(other); } |
| 324 iterator& operator++() { |
| 325 DCHECK(current_ != NULL); |
| 326 index_++; |
| 327 current_ = next_; |
| 328 next_ = (current_ == NULL) ? NULL : current_->next; |
| 329 return *this; |
| 330 } |
| 331 iterator& operator++(int) { |
| 332 iterator result(*this); |
| 333 ++(*this); |
| 334 return result; |
| 335 } |
| 336 |
| 337 private: |
| 338 friend class GenericNode<B, S>::UseEdges; |
| 339 |
| 340 iterator() : current_(NULL), next_(NULL), index_(0) {} |
| 341 explicit iterator(GenericNode<B, S>* node) |
| 342 : current_(node->first_use_), |
| 343 next_(current_ == NULL ? NULL : current_->next), |
| 344 index_(0) {} |
| 345 |
| 346 bool Equals(const iterator& other) const { |
| 347 return other.current_ == current_; |
| 348 } |
| 349 |
| 350 Input* CurrentInput() const { |
| 351 return current_->from->GetInputRecordPtr(current_->input_index); |
| 352 } |
| 353 |
| 354 typename GenericNode<B, S>::Use* current_; |
| 355 typename GenericNode<B, S>::Use* next_; |
| 356 int index_; |
| 357 }; |
| 358 |
| 359 |
| 360 // A forward iterator to visit the uses edges of a node. The edges are returned |
| 361 // in the order in which they were added as inputs. |
| 362 template <class B, class S> |
232 class GenericNode<B, S>::Uses::iterator { | 363 class GenericNode<B, S>::Uses::iterator { |
233 public: | 364 public: |
234 iterator(const typename GenericNode<B, S>::Uses::iterator& other) // NOLINT | 365 iterator(const typename GenericNode<B, S>::Uses::iterator& other) // NOLINT |
235 : current_(other.current_), | 366 : current_(other.current_) {} |
236 index_(other.index_) {} | |
237 | 367 |
238 S* operator*() { return static_cast<S*>(current_->from); } | 368 S* operator*() { return static_cast<S*>(current_->from); } |
239 typename GenericNode<B, S>::Edge edge() { | |
240 return typename GenericNode::Edge(CurrentInput()); | |
241 } | |
242 | 369 |
243 bool operator==(const iterator& other) { return other.current_ == current_; } | 370 bool operator==(const iterator& other) { return other.current_ == current_; } |
244 bool operator!=(const iterator& other) { return other.current_ != current_; } | 371 bool operator!=(const iterator& other) { return other.current_ != current_; } |
245 iterator& operator++() { | 372 iterator& operator++() { |
246 DCHECK(current_ != NULL); | 373 DCHECK(current_ != NULL); |
247 index_++; | |
248 current_ = current_->next; | 374 current_ = current_->next; |
249 return *this; | 375 return *this; |
250 } | 376 } |
251 iterator& UpdateToAndIncrement(GenericNode<B, S>* new_to) { | |
252 DCHECK(current_ != NULL); | |
253 index_++; | |
254 typename GenericNode<B, S>::Input* input = CurrentInput(); | |
255 current_ = current_->next; | |
256 input->Update(new_to); | |
257 return *this; | |
258 } | |
259 int index() const { return index_; } | |
260 | 377 |
261 private: | 378 private: |
262 friend class GenericNode<B, S>::Uses; | 379 friend class GenericNode<B, S>::Uses; |
263 | 380 |
264 iterator() : current_(NULL), index_(0) {} | 381 iterator() : current_(NULL) {} |
265 explicit iterator(GenericNode<B, S>* node) | 382 explicit iterator(GenericNode<B, S>* node) : current_(node->first_use_) {} |
266 : current_(node->first_use_), index_(0) {} | |
267 | 383 |
268 Input* CurrentInput() const { | 384 Input* CurrentInput() const { |
269 return current_->from->GetInputRecordPtr(current_->input_index); | 385 return current_->from->GetInputRecordPtr(current_->input_index); |
270 } | 386 } |
271 | 387 |
272 typename GenericNode<B, S>::Use* current_; | 388 typename GenericNode<B, S>::Use* current_; |
273 int index_; | |
274 }; | 389 }; |
275 } | 390 } |
276 } | 391 } |
277 } // namespace v8::internal::compiler | 392 } // namespace v8::internal::compiler |
278 | 393 |
279 #endif // V8_COMPILER_GENERIC_NODE_H_ | 394 #endif // V8_COMPILER_GENERIC_NODE_H_ |
OLD | NEW |