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_NODE_H_ | 5 #ifndef V8_COMPILER_NODE_H_ |
6 #define V8_COMPILER_NODE_H_ | 6 #define V8_COMPILER_NODE_H_ |
7 | 7 |
8 #include <deque> | 8 #include <deque> |
9 #include <set> | 9 #include <set> |
10 #include <vector> | 10 #include <vector> |
11 | 11 |
12 #include "src/v8.h" | 12 #include "src/v8.h" |
13 | 13 |
14 #include "src/compiler/generic-algorithm.h" | 14 #include "src/compiler/generic-algorithm.h" |
15 #include "src/compiler/opcodes.h" | 15 #include "src/compiler/opcodes.h" |
16 #include "src/compiler/operator.h" | 16 #include "src/compiler/operator.h" |
17 #include "src/types.h" | 17 #include "src/types.h" |
18 #include "src/zone.h" | 18 #include "src/zone.h" |
19 #include "src/zone-allocator.h" | 19 #include "src/zone-allocator.h" |
20 #include "src/zone-containers.h" | 20 #include "src/zone-containers.h" |
21 | 21 |
22 namespace v8 { | 22 namespace v8 { |
23 namespace internal { | 23 namespace internal { |
24 namespace compiler { | 24 namespace compiler { |
25 | 25 |
26 class Graph; | 26 class Graph; |
27 class Edge; | |
Michael Starzinger
2014/12/02 09:24:39
nit: Please alpha-sort.
danno
2014/12/02 12:54:00
Done.
| |
27 | 28 |
28 // Marks are used during traversal of the graph to distinguish states of nodes. | 29 // Marks are used during traversal of the graph to distinguish states of nodes. |
29 // Each node has a mark which is a monotonically increasing integer, and a | 30 // Each node has a mark which is a monotonically increasing integer, and a |
30 // {NodeMarker} has a range of values that indicate states of a node. | 31 // {NodeMarker} has a range of values that indicate states of a node. |
31 typedef uint32_t Mark; | 32 typedef uint32_t Mark; |
32 | 33 |
33 class NodeData { | 34 class NodeData { |
34 public: | 35 public: |
35 const Operator* op() const { return op_; } | 36 const Operator* op() const { return op_; } |
36 void set_op(const Operator* op) { op_ = op; } | 37 void set_op(const Operator* op) { op_ = op; } |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
100 } | 101 } |
101 return current->from; | 102 return current->from; |
102 } | 103 } |
103 inline void ReplaceUses(Node* replace_to); | 104 inline void ReplaceUses(Node* replace_to); |
104 template <class UnaryPredicate> | 105 template <class UnaryPredicate> |
105 inline void ReplaceUsesIf(UnaryPredicate pred, Node* replace_to); | 106 inline void ReplaceUsesIf(UnaryPredicate pred, Node* replace_to); |
106 inline void RemoveAllInputs(); | 107 inline void RemoveAllInputs(); |
107 | 108 |
108 inline void TrimInputCount(int input_count); | 109 inline void TrimInputCount(int input_count); |
109 | 110 |
111 class InputEdges { | |
112 public: | |
113 class iterator; | |
114 iterator begin() const; | |
115 iterator end() const; | |
116 bool empty() const; | |
117 | |
118 explicit InputEdges(Node* node) : node_(node) {} | |
119 | |
120 private: | |
121 Node* node_; | |
122 }; | |
123 | |
110 class Inputs { | 124 class Inputs { |
111 public: | 125 public: |
112 class iterator; | 126 class iterator; |
113 iterator begin(); | 127 iterator begin() const; |
114 iterator end(); | 128 iterator end() const; |
129 bool empty() const; | |
115 | 130 |
116 explicit Inputs(Node* node) : node_(node) {} | 131 explicit Inputs(Node* node) : node_(node) {} |
117 | 132 |
118 private: | 133 private: |
119 Node* node_; | 134 Node* node_; |
120 }; | 135 }; |
121 | 136 |
122 Inputs inputs() { return Inputs(this); } | 137 Inputs inputs() { return Inputs(this); } |
138 InputEdges input_edges() { return InputEdges(this); } | |
139 | |
140 class UseEdges { | |
141 public: | |
142 class iterator; | |
143 iterator begin() const; | |
144 iterator end() const; | |
145 bool empty() const; | |
146 | |
147 explicit UseEdges(Node* node) : node_(node) {} | |
148 | |
149 private: | |
150 Node* node_; | |
151 }; | |
123 | 152 |
124 class Uses { | 153 class Uses { |
125 public: | 154 public: |
126 class iterator; | 155 class iterator; |
127 iterator begin(); | 156 iterator begin() const; |
128 iterator end(); | 157 iterator end() const; |
129 bool empty(); | 158 bool empty() const; |
130 | 159 |
131 explicit Uses(Node* node) : node_(node) {} | 160 explicit Uses(Node* node) : node_(node) {} |
132 | 161 |
133 private: | 162 private: |
134 Node* node_; | 163 Node* node_; |
135 }; | 164 }; |
136 | 165 |
137 Uses uses() { return Uses(this); } | 166 Uses uses() { return Uses(this); } |
138 | 167 UseEdges use_edges() { return UseEdges(this); } |
139 class Edge; | |
140 | 168 |
141 bool OwnedBy(Node* owner) const; | 169 bool OwnedBy(Node* owner) const; |
142 | 170 |
143 static Node* New(Graph* graph, int input_count, Node** inputs, | 171 static Node* New(Graph* graph, int input_count, Node** inputs, |
144 bool has_extensible_inputs); | 172 bool has_extensible_inputs); |
145 | 173 |
146 protected: | 174 protected: |
147 friend class Graph; | 175 friend class Graph; |
176 friend class Edge; | |
148 | 177 |
149 class Use : public ZoneObject { | 178 class Use : public ZoneObject { |
150 public: | 179 public: |
151 Node* from; | 180 Node* from; |
152 Use* next; | 181 Use* next; |
153 Use* prev; | 182 Use* prev; |
154 int input_index; | 183 int input_index; |
155 }; | 184 }; |
156 | 185 |
157 class Input { | 186 class Input { |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
200 } inputs_; | 229 } inputs_; |
201 int use_count_; | 230 int use_count_; |
202 Use* first_use_; | 231 Use* first_use_; |
203 Use* last_use_; | 232 Use* last_use_; |
204 | 233 |
205 DISALLOW_COPY_AND_ASSIGN(Node); | 234 DISALLOW_COPY_AND_ASSIGN(Node); |
206 }; | 235 }; |
207 | 236 |
208 // An encapsulation for information associated with a single use of node as a | 237 // An encapsulation for information associated with a single use of node as a |
209 // input from another node, allowing access to both the defining node and | 238 // input from another node, allowing access to both the defining node and |
210 // the ndoe having the input. | 239 // the node having the input. |
211 class Node::Edge { | 240 class Edge { |
212 public: | 241 public: |
213 Node* from() const { return input_->use->from; } | 242 Node* from() const { return input_->use->from; } |
214 Node* to() const { return input_->to; } | 243 Node* to() const { return input_->to; } |
215 int index() const { | 244 int index() const { |
216 int index = input_->use->input_index; | 245 int index = input_->use->input_index; |
217 DCHECK(index < input_->use->from->input_count_); | 246 DCHECK(index < input_->use->from->input_count_); |
218 return index; | 247 return index; |
219 } | 248 } |
220 | 249 |
250 bool operator==(const Edge& other) { return input_ == other.input_; } | |
251 bool operator!=(const Edge& other) { return !(*this == other); } | |
252 | |
253 void UpdateTo(Node* new_to) { input_->Update(new_to); } | |
254 | |
221 private: | 255 private: |
222 friend class Node::Uses::iterator; | 256 friend class Node::Uses::iterator; |
223 friend class Node::Inputs::iterator; | 257 friend class Node::Inputs::iterator; |
258 friend class Node::UseEdges::iterator; | |
259 friend class Node::InputEdges::iterator; | |
224 | 260 |
225 explicit Edge(Node::Input* input) : input_(input) {} | 261 explicit Edge(Node::Input* input) : input_(input) {} |
226 | 262 |
227 Node::Input* input_; | 263 Node::Input* input_; |
228 }; | 264 }; |
229 | 265 |
230 // A forward iterator to visit the nodes which are depended upon by a node | 266 |
231 // in the order of input. | 267 // A forward iterator to visit the edges for the input dependencies of a node.. |
232 class Node::Inputs::iterator { | 268 class Node::InputEdges::iterator { |
233 public: | 269 public: |
234 iterator(const Node::Inputs::iterator& other) // NOLINT | 270 typedef std::forward_iterator_tag iterator_category; |
235 : node_(other.node_), | 271 typedef int difference_type; |
236 index_(other.index_) {} | 272 typedef Edge value_type; |
273 typedef Edge* pointer; | |
274 typedef Edge& reference; | |
275 iterator(const typename Node::InputEdges::iterator& other) // NOLINT | |
276 : input_(other.input_) {} | |
277 iterator() : input_(NULL) {} | |
237 | 278 |
238 Node* operator*() { return GetInput()->to; } | 279 Edge operator*() const { return Edge(input_); } |
239 Node::Edge edge() { return Node::Edge(GetInput()); } | 280 bool operator==(const iterator& other) const { return Equals(other); } |
240 bool operator==(const iterator& other) const { | 281 bool operator!=(const iterator& other) const { return !Equals(other); } |
241 return other.index_ == index_ && other.node_ == node_; | |
242 } | |
243 bool operator!=(const iterator& other) const { return !(other == *this); } | |
244 iterator& operator++() { | 282 iterator& operator++() { |
245 DCHECK(node_ != NULL); | 283 DCHECK(input_ != NULL); |
246 DCHECK(index_ < node_->input_count_); | 284 Edge edge(input_); |
247 ++index_; | 285 Node* from = edge.from(); |
286 SetInput(from, input_->use->input_index + 1); | |
248 return *this; | 287 return *this; |
249 } | 288 } |
250 iterator& UpdateToAndIncrement(Node* new_to) { | 289 iterator operator++(int) { |
251 Node::Input* input = GetInput(); | 290 iterator result(*this); |
252 input->Update(new_to); | 291 ++(*this); |
253 index_++; | 292 return result; |
254 return *this; | |
255 } | 293 } |
256 int index() { return index_; } | |
257 | 294 |
258 private: | 295 private: |
259 friend class Node; | 296 friend class Node; |
260 | 297 |
261 explicit iterator(Node* node, int index) : node_(node), index_(index) {} | 298 explicit iterator(Node* from, int index = 0) : input_(NULL) { |
299 SetInput(from, index); | |
300 } | |
262 | 301 |
263 Input* GetInput() const { return node_->GetInputRecordPtr(index_); } | 302 bool Equals(const iterator& other) const { return other.input_ == input_; } |
303 void SetInput(Node* from, int index) { | |
304 DCHECK(index >= 0 && index <= from->InputCount()); | |
305 if (index < from->InputCount()) { | |
306 input_ = from->GetInputRecordPtr(index); | |
307 } else { | |
308 input_ = NULL; | |
309 } | |
310 } | |
264 | 311 |
265 Node* node_; | 312 Input* input_; |
266 int index_; | |
267 }; | 313 }; |
268 | 314 |
315 // A forward iterator to visit the inputs of a node. | |
316 class Node::Inputs::iterator { | |
317 public: | |
318 typedef std::forward_iterator_tag iterator_category; | |
319 typedef int difference_type; | |
320 typedef Node* value_type; | |
321 typedef Node** pointer; | |
322 typedef Node*& reference; | |
323 | |
324 iterator(const Node::Inputs::iterator& other) // NOLINT | |
325 : iter_(other.iter_) {} | |
326 | |
327 Node* operator*() const { return (*iter_).to(); } | |
328 bool operator==(const iterator& other) const { return Equals(other); } | |
329 bool operator!=(const iterator& other) const { return !Equals(other); } | |
330 iterator& operator++() { | |
331 ++iter_; | |
332 return *this; | |
333 } | |
334 iterator operator++(int) { | |
335 iterator result(*this); | |
336 ++(*this); | |
337 return result; | |
338 } | |
339 | |
340 | |
341 private: | |
342 friend class Node::Inputs; | |
343 | |
344 explicit iterator(Node* node, int index) : iter_(node, index) {} | |
345 | |
346 bool Equals(const iterator& other) const { return other.iter_ == iter_; } | |
347 | |
348 Node::InputEdges::iterator iter_; | |
349 }; | |
350 | |
351 // A forward iterator to visit the uses edges of a node. The edges are returned | |
352 // in | |
353 // the order in which they were added as inputs. | |
354 class Node::UseEdges::iterator { | |
355 public: | |
356 iterator(const typename Node::UseEdges::iterator& other) // NOLINT | |
357 : current_(other.current_), | |
358 next_(other.next_) {} | |
359 | |
360 Edge operator*() const { return Edge(CurrentInput()); } | |
361 | |
362 bool operator==(const iterator& other) { return Equals(other); } | |
363 bool operator!=(const iterator& other) { return !Equals(other); } | |
364 iterator& operator++() { | |
365 DCHECK(current_ != NULL); | |
366 current_ = next_; | |
367 next_ = (current_ == NULL) ? NULL : current_->next; | |
368 return *this; | |
369 } | |
370 iterator operator++(int) { | |
371 iterator result(*this); | |
372 ++(*this); | |
373 return result; | |
374 } | |
375 | |
376 private: | |
377 friend class Node::UseEdges; | |
378 | |
379 iterator() : current_(NULL), next_(NULL) {} | |
380 explicit iterator(Node* node) | |
381 : current_(node->first_use_), | |
382 next_(current_ == NULL ? NULL : current_->next) {} | |
383 | |
384 bool Equals(const iterator& other) const { | |
385 return other.current_ == current_; | |
386 } | |
387 | |
388 Input* CurrentInput() const { | |
389 return current_->from->GetInputRecordPtr(current_->input_index); | |
390 } | |
391 | |
392 typename Node::Use* current_; | |
393 typename Node::Use* next_; | |
394 }; | |
395 | |
396 | |
269 // A forward iterator to visit the uses of a node. The uses are returned in | 397 // A forward iterator to visit the uses of a node. The uses are returned in |
270 // the order in which they were added as inputs. | 398 // the order in which they were added as inputs. |
271 class Node::Uses::iterator { | 399 class Node::Uses::iterator { |
272 public: | 400 public: |
273 iterator(const Node::Uses::iterator& other) // NOLINT | 401 iterator(const Node::Uses::iterator& other) // NOLINT |
274 : current_(other.current_), | 402 : current_(other.current_) {} |
275 index_(other.index_) {} | |
276 | 403 |
277 Node* operator*() { return current_->from; } | 404 Node* operator*() { return current_->from; } |
278 Node::Edge edge() { return Node::Edge(CurrentInput()); } | |
279 | 405 |
280 bool operator==(const iterator& other) { return other.current_ == current_; } | 406 bool operator==(const iterator& other) { return other.current_ == current_; } |
281 bool operator!=(const iterator& other) { return other.current_ != current_; } | 407 bool operator!=(const iterator& other) { return other.current_ != current_; } |
282 iterator& operator++() { | 408 iterator& operator++() { |
283 DCHECK(current_ != NULL); | 409 DCHECK(current_ != NULL); |
284 index_++; | |
285 current_ = current_->next; | 410 current_ = current_->next; |
286 return *this; | 411 return *this; |
287 } | 412 } |
288 iterator& UpdateToAndIncrement(Node* new_to) { | |
289 DCHECK(current_ != NULL); | |
290 index_++; | |
291 Node::Input* input = CurrentInput(); | |
292 current_ = current_->next; | |
293 input->Update(new_to); | |
294 return *this; | |
295 } | |
296 int index() const { return index_; } | |
297 | 413 |
298 private: | 414 private: |
299 friend class Node::Uses; | 415 friend class Node::Uses; |
300 | 416 |
301 iterator() : current_(NULL), index_(0) {} | 417 iterator() : current_(NULL) {} |
302 explicit iterator(Node* node) : current_(node->first_use_), index_(0) {} | 418 explicit iterator(Node* node) : current_(node->first_use_) {} |
303 | 419 |
304 Input* CurrentInput() const { | 420 Input* CurrentInput() const { |
305 return current_->from->GetInputRecordPtr(current_->input_index); | 421 return current_->from->GetInputRecordPtr(current_->input_index); |
306 } | 422 } |
307 | 423 |
308 Node::Use* current_; | 424 Node::Use* current_; |
309 int index_; | |
310 }; | 425 }; |
311 | 426 |
312 std::ostream& operator<<(std::ostream& os, const Node& n); | 427 std::ostream& operator<<(std::ostream& os, const Node& n); |
313 | 428 |
314 typedef GenericGraphVisit::NullNodeVisitor NullNodeVisitor; | 429 typedef GenericGraphVisit::NullNodeVisitor NullNodeVisitor; |
315 | 430 |
316 typedef std::set<Node*, std::less<Node*>, zone_allocator<Node*> > NodeSet; | 431 typedef std::set<Node*, std::less<Node*>, zone_allocator<Node*> > NodeSet; |
317 typedef NodeSet::iterator NodeSetIter; | 432 typedef NodeSet::iterator NodeSetIter; |
318 typedef NodeSet::reverse_iterator NodeSetRIter; | 433 typedef NodeSet::reverse_iterator NodeSetRIter; |
319 | 434 |
(...skipping 10 matching lines...) Expand all Loading... | |
330 | 445 |
331 typedef Node::Uses::iterator UseIter; | 446 typedef Node::Uses::iterator UseIter; |
332 typedef Node::Inputs::iterator InputIter; | 447 typedef Node::Inputs::iterator InputIter; |
333 | 448 |
334 // Helper to extract parameters from Operator1<*> nodes. | 449 // Helper to extract parameters from Operator1<*> nodes. |
335 template <typename T> | 450 template <typename T> |
336 static inline const T& OpParameter(const Node* node) { | 451 static inline const T& OpParameter(const Node* node) { |
337 return OpParameter<T>(node->op()); | 452 return OpParameter<T>(node->op()); |
338 } | 453 } |
339 | 454 |
340 inline Node::Inputs::iterator Node::Inputs::begin() { | 455 inline Node::InputEdges::iterator Node::InputEdges::begin() const { |
456 return Node::InputEdges::iterator(this->node_, 0); | |
457 } | |
458 | |
459 inline Node::InputEdges::iterator Node::InputEdges::end() const { | |
460 return Node::InputEdges::iterator(this->node_, this->node_->InputCount()); | |
461 } | |
462 | |
463 inline Node::Inputs::iterator Node::Inputs::begin() const { | |
341 return Node::Inputs::iterator(this->node_, 0); | 464 return Node::Inputs::iterator(this->node_, 0); |
342 } | 465 } |
343 | 466 |
344 inline Node::Inputs::iterator Node::Inputs::end() { | 467 inline Node::Inputs::iterator Node::Inputs::end() const { |
345 return Node::Inputs::iterator(this->node_, this->node_->InputCount()); | 468 return Node::Inputs::iterator(this->node_, this->node_->InputCount()); |
346 } | 469 } |
347 | 470 |
348 inline Node::Uses::iterator Node::Uses::begin() { | 471 inline Node::UseEdges::iterator Node::UseEdges::begin() const { |
472 return Node::UseEdges::iterator(this->node_); | |
473 } | |
474 | |
475 inline Node::UseEdges::iterator Node::UseEdges::end() const { | |
476 return Node::UseEdges::iterator(); | |
477 } | |
478 | |
479 inline Node::Uses::iterator Node::Uses::begin() const { | |
349 return Node::Uses::iterator(this->node_); | 480 return Node::Uses::iterator(this->node_); |
350 } | 481 } |
351 | 482 |
352 inline Node::Uses::iterator Node::Uses::end() { return Node::Uses::iterator(); } | 483 inline Node::Uses::iterator Node::Uses::end() const { |
484 return Node::Uses::iterator(); | |
485 } | |
353 | 486 |
354 inline bool Node::Uses::empty() { return begin() == end(); } | 487 inline bool Node::InputEdges::empty() const { return begin() == end(); } |
488 inline bool Node::Uses::empty() const { return begin() == end(); } | |
489 inline bool Node::UseEdges::empty() const { return begin() == end(); } | |
490 inline bool Node::Inputs::empty() const { return begin() == end(); } | |
355 | 491 |
356 inline void Node::ReplaceUses(Node* replace_to) { | 492 inline void Node::ReplaceUses(Node* replace_to) { |
357 for (Use* use = first_use_; use != NULL; use = use->next) { | 493 for (Use* use = first_use_; use != NULL; use = use->next) { |
358 use->from->GetInputRecordPtr(use->input_index)->to = replace_to; | 494 use->from->GetInputRecordPtr(use->input_index)->to = replace_to; |
359 } | 495 } |
360 if (replace_to->last_use_ == NULL) { | 496 if (replace_to->last_use_ == NULL) { |
361 DCHECK_EQ(NULL, replace_to->first_use_); | 497 DCHECK_EQ(NULL, replace_to->first_use_); |
362 replace_to->first_use_ = first_use_; | 498 replace_to->first_use_ = first_use_; |
363 replace_to->last_use_ = last_use_; | 499 replace_to->last_use_ = last_use_; |
364 } else if (first_use_ != NULL) { | 500 } else if (first_use_ != NULL) { |
(...skipping 15 matching lines...) Expand all Loading... | |
380 if (pred(use->from)) { | 516 if (pred(use->from)) { |
381 RemoveUse(use); | 517 RemoveUse(use); |
382 replace_to->AppendUse(use); | 518 replace_to->AppendUse(use); |
383 use->from->GetInputRecordPtr(use->input_index)->to = replace_to; | 519 use->from->GetInputRecordPtr(use->input_index)->to = replace_to; |
384 } | 520 } |
385 use = next; | 521 use = next; |
386 } | 522 } |
387 } | 523 } |
388 | 524 |
389 inline void Node::RemoveAllInputs() { | 525 inline void Node::RemoveAllInputs() { |
390 for (Inputs::iterator iter(inputs().begin()); iter != inputs().end(); | 526 for (Edge edge : input_edges()) { |
391 ++iter) { | 527 edge.UpdateTo(NULL); |
392 iter.GetInput()->Update(NULL); | |
393 } | 528 } |
394 } | 529 } |
395 | 530 |
396 inline void Node::TrimInputCount(int new_input_count) { | 531 inline void Node::TrimInputCount(int new_input_count) { |
397 if (new_input_count == input_count_) return; // Nothing to do. | 532 if (new_input_count == input_count_) return; // Nothing to do. |
398 | 533 |
399 DCHECK(new_input_count < input_count_); | 534 DCHECK(new_input_count < input_count_); |
400 | 535 |
401 // Update inline inputs. | 536 // Update inline inputs. |
402 for (int i = new_input_count; i < input_count_; i++) { | 537 for (int i = new_input_count; i < input_count_; i++) { |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
508 inline bool Node::OwnedBy(Node* owner) const { | 643 inline bool Node::OwnedBy(Node* owner) const { |
509 return first_use_ != NULL && first_use_->from == owner && | 644 return first_use_ != NULL && first_use_->from == owner && |
510 first_use_->next == NULL; | 645 first_use_->next == NULL; |
511 } | 646 } |
512 | 647 |
513 } // namespace compiler | 648 } // namespace compiler |
514 } // namespace internal | 649 } // namespace internal |
515 } // namespace v8 | 650 } // namespace v8 |
516 | 651 |
517 #endif // V8_COMPILER_NODE_H_ | 652 #endif // V8_COMPILER_NODE_H_ |
OLD | NEW |