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 "src/compiler/opcodes.h" | 8 #include "src/compiler/opcodes.h" |
9 #include "src/compiler/operator.h" | 9 #include "src/compiler/operator.h" |
10 #include "src/compiler/types.h" | 10 #include "src/compiler/types.h" |
(...skipping 28 matching lines...) Expand all Loading... |
39 // In addition Nodes only contain a mutable Operator that may change during | 39 // In addition Nodes only contain a mutable Operator that may change during |
40 // compilation, e.g. during lowering passes. Other information that needs to be | 40 // compilation, e.g. during lowering passes. Other information that needs to be |
41 // associated with Nodes during compilation must be stored out-of-line indexed | 41 // associated with Nodes during compilation must be stored out-of-line indexed |
42 // by the Node's id. | 42 // by the Node's id. |
43 class V8_EXPORT_PRIVATE Node final { | 43 class V8_EXPORT_PRIVATE Node final { |
44 public: | 44 public: |
45 static Node* New(Zone* zone, NodeId id, const Operator* op, int input_count, | 45 static Node* New(Zone* zone, NodeId id, const Operator* op, int input_count, |
46 Node* const* inputs, bool has_extensible_inputs); | 46 Node* const* inputs, bool has_extensible_inputs); |
47 static Node* Clone(Zone* zone, NodeId id, const Node* node); | 47 static Node* Clone(Zone* zone, NodeId id, const Node* node); |
48 | 48 |
49 bool IsDead() const { return InputCount() > 0 && !InputAt(0); } | 49 inline bool IsDead() const; |
50 void Kill(); | 50 void Kill(); |
51 | 51 |
52 const Operator* op() const { return op_; } | 52 const Operator* op() const { return op_; } |
53 | 53 |
54 IrOpcode::Value opcode() const { | 54 IrOpcode::Value opcode() const { |
55 DCHECK(op_->opcode() <= IrOpcode::kLast); | 55 DCHECK(op_->opcode() <= IrOpcode::kLast); |
56 return static_cast<IrOpcode::Value>(op_->opcode()); | 56 return static_cast<IrOpcode::Value>(op_->opcode()); |
57 } | 57 } |
58 | 58 |
59 NodeId id() const { return IdField::decode(bit_field_); } | 59 NodeId id() const { return IdField::decode(bit_field_); } |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
102 void AppendInput(Zone* zone, Node* new_to); | 102 void AppendInput(Zone* zone, Node* new_to); |
103 void InsertInput(Zone* zone, int index, Node* new_to); | 103 void InsertInput(Zone* zone, int index, Node* new_to); |
104 void InsertInputs(Zone* zone, int index, int count); | 104 void InsertInputs(Zone* zone, int index, int count); |
105 void RemoveInput(int index); | 105 void RemoveInput(int index); |
106 void NullAllInputs(); | 106 void NullAllInputs(); |
107 void TrimInputCount(int new_input_count); | 107 void TrimInputCount(int new_input_count); |
108 | 108 |
109 int UseCount() const; | 109 int UseCount() const; |
110 void ReplaceUses(Node* replace_to); | 110 void ReplaceUses(Node* replace_to); |
111 | 111 |
112 class InputEdges final { | 112 class InputEdges; |
113 public: | 113 inline InputEdges input_edges(); |
114 typedef Edge value_type; | |
115 | 114 |
116 class iterator; | 115 class Inputs; |
117 inline iterator begin() const; | 116 inline Inputs inputs() const; |
118 inline iterator end() const; | |
119 | |
120 bool empty() const; | |
121 | |
122 explicit InputEdges(Node* node) : node_(node) {} | |
123 | |
124 private: | |
125 Node* node_; | |
126 }; | |
127 | |
128 InputEdges input_edges() { return InputEdges(this); } | |
129 | |
130 class V8_EXPORT_PRIVATE Inputs final { | |
131 public: | |
132 typedef Node* value_type; | |
133 | |
134 class const_iterator; | |
135 inline const_iterator begin() const; | |
136 inline const_iterator end() const; | |
137 | |
138 bool empty() const; | |
139 | |
140 explicit Inputs(Node* node) : node_(node) {} | |
141 | |
142 private: | |
143 Node* node_; | |
144 }; | |
145 | |
146 Inputs inputs() { return Inputs(this); } | |
147 | 117 |
148 class UseEdges final { | 118 class UseEdges final { |
149 public: | 119 public: |
150 typedef Edge value_type; | 120 typedef Edge value_type; |
151 | 121 |
152 class iterator; | 122 class iterator; |
153 inline iterator begin() const; | 123 inline iterator begin() const; |
154 inline iterator end() const; | 124 inline iterator end() const; |
155 | 125 |
156 bool empty() const; | 126 bool empty() const; |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 typedef ZoneVector<Node*> NodeVector; | 308 typedef ZoneVector<Node*> NodeVector; |
339 typedef ZoneVector<NodeVector> NodeVectorVector; | 309 typedef ZoneVector<NodeVector> NodeVectorVector; |
340 | 310 |
341 | 311 |
342 // Helper to extract parameters from Operator1<*> nodes. | 312 // Helper to extract parameters from Operator1<*> nodes. |
343 template <typename T> | 313 template <typename T> |
344 static inline const T& OpParameter(const Node* node) { | 314 static inline const T& OpParameter(const Node* node) { |
345 return OpParameter<T>(node->op()); | 315 return OpParameter<T>(node->op()); |
346 } | 316 } |
347 | 317 |
| 318 class Node::InputEdges final { |
| 319 public: |
| 320 typedef Edge value_type; |
| 321 |
| 322 class iterator; |
| 323 inline iterator begin() const; |
| 324 inline iterator end() const; |
| 325 |
| 326 bool empty() const { return count_ == 0; } |
| 327 int count() const { return count_; } |
| 328 |
| 329 inline value_type operator[](int index) const; |
| 330 |
| 331 InputEdges(Node** input_root, Use* use_root, int count) |
| 332 : input_root_(input_root), use_root_(use_root), count_(count) {} |
| 333 |
| 334 private: |
| 335 Node** input_root_; |
| 336 Use* use_root_; |
| 337 int count_; |
| 338 }; |
| 339 |
| 340 class V8_EXPORT_PRIVATE Node::Inputs final { |
| 341 public: |
| 342 typedef Node* value_type; |
| 343 |
| 344 class const_iterator; |
| 345 inline const_iterator begin() const; |
| 346 inline const_iterator end() const; |
| 347 |
| 348 bool empty() const { return count_ == 0; } |
| 349 int count() const { return count_; } |
| 350 |
| 351 inline value_type operator[](int index) const; |
| 352 |
| 353 explicit Inputs(Node* const* input_root, int count) |
| 354 : input_root_(input_root), count_(count) {} |
| 355 |
| 356 private: |
| 357 Node* const* input_root_; |
| 358 int count_; |
| 359 }; |
348 | 360 |
349 // An encapsulation for information associated with a single use of node as a | 361 // An encapsulation for information associated with a single use of node as a |
350 // input from another node, allowing access to both the defining node and | 362 // input from another node, allowing access to both the defining node and |
351 // the node having the input. | 363 // the node having the input. |
352 class Edge final { | 364 class Edge final { |
353 public: | 365 public: |
354 Node* from() const { return use_->from(); } | 366 Node* from() const { return use_->from(); } |
355 Node* to() const { return *input_ptr_; } | 367 Node* to() const { return *input_ptr_; } |
356 int index() const { | 368 int index() const { |
357 int const index = use_->input_index(); | 369 int const index = use_->input_index(); |
358 DCHECK_LT(index, use_->from()->InputCount()); | 370 DCHECK_LT(index, use_->from()->InputCount()); |
359 return index; | 371 return index; |
360 } | 372 } |
361 | 373 |
362 bool operator==(const Edge& other) { return input_ptr_ == other.input_ptr_; } | 374 bool operator==(const Edge& other) { return input_ptr_ == other.input_ptr_; } |
363 bool operator!=(const Edge& other) { return !(*this == other); } | 375 bool operator!=(const Edge& other) { return !(*this == other); } |
364 | 376 |
365 void UpdateTo(Node* new_to) { | 377 void UpdateTo(Node* new_to) { |
366 Node* old_to = *input_ptr_; | 378 Node* old_to = *input_ptr_; |
367 if (old_to != new_to) { | 379 if (old_to != new_to) { |
368 if (old_to) old_to->RemoveUse(use_); | 380 if (old_to) old_to->RemoveUse(use_); |
369 *input_ptr_ = new_to; | 381 *input_ptr_ = new_to; |
370 if (new_to) new_to->AppendUse(use_); | 382 if (new_to) new_to->AppendUse(use_); |
371 } | 383 } |
372 } | 384 } |
373 | 385 |
374 private: | 386 private: |
375 friend class Node::UseEdges::iterator; | 387 friend class Node::UseEdges::iterator; |
| 388 friend class Node::InputEdges; |
376 friend class Node::InputEdges::iterator; | 389 friend class Node::InputEdges::iterator; |
377 | 390 |
378 Edge(Node::Use* use, Node** input_ptr) : use_(use), input_ptr_(input_ptr) { | 391 Edge(Node::Use* use, Node** input_ptr) : use_(use), input_ptr_(input_ptr) { |
379 DCHECK_NOT_NULL(use); | 392 DCHECK_NOT_NULL(use); |
380 DCHECK_NOT_NULL(input_ptr); | 393 DCHECK_NOT_NULL(input_ptr); |
381 DCHECK_EQ(input_ptr, use->input_ptr()); | 394 DCHECK_EQ(input_ptr, use->input_ptr()); |
382 } | 395 } |
383 | 396 |
384 Node::Use* use_; | 397 Node::Use* use_; |
385 Node** input_ptr_; | 398 Node** input_ptr_; |
386 }; | 399 }; |
387 | 400 |
| 401 bool Node::IsDead() const { |
| 402 Node::Inputs inputs = this->inputs(); |
| 403 return inputs.count() > 0 && inputs[0] == nullptr; |
| 404 } |
| 405 |
| 406 Node::InputEdges Node::input_edges() { |
| 407 int inline_count = InlineCountField::decode(bit_field_); |
| 408 if (inline_count != kOutlineMarker) { |
| 409 return InputEdges(inputs_.inline_, reinterpret_cast<Use*>(this) - 1, |
| 410 inline_count); |
| 411 } else { |
| 412 return InputEdges(inputs_.outline_->inputs_, |
| 413 reinterpret_cast<Use*>(inputs_.outline_) - 1, |
| 414 inputs_.outline_->count_); |
| 415 } |
| 416 } |
| 417 |
| 418 Node::Inputs Node::inputs() const { |
| 419 int inline_count = InlineCountField::decode(bit_field_); |
| 420 if (inline_count != kOutlineMarker) { |
| 421 return Inputs(inputs_.inline_, inline_count); |
| 422 } else { |
| 423 return Inputs(inputs_.outline_->inputs_, inputs_.outline_->count_); |
| 424 } |
| 425 } |
388 | 426 |
389 // A forward iterator to visit the edges for the input dependencies of a node. | 427 // A forward iterator to visit the edges for the input dependencies of a node. |
390 class Node::InputEdges::iterator final { | 428 class Node::InputEdges::iterator final { |
391 public: | 429 public: |
392 typedef std::forward_iterator_tag iterator_category; | 430 typedef std::forward_iterator_tag iterator_category; |
393 typedef int difference_type; | 431 typedef std::ptrdiff_t difference_type; |
394 typedef Edge value_type; | 432 typedef Edge value_type; |
395 typedef Edge* pointer; | 433 typedef Edge* pointer; |
396 typedef Edge& reference; | 434 typedef Edge& reference; |
397 | 435 |
398 iterator() : use_(nullptr), input_ptr_(nullptr) {} | 436 iterator() : use_(nullptr), input_ptr_(nullptr) {} |
399 iterator(const iterator& other) | 437 iterator(const iterator& other) |
400 : use_(other.use_), input_ptr_(other.input_ptr_) {} | 438 : use_(other.use_), input_ptr_(other.input_ptr_) {} |
401 | 439 |
402 Edge operator*() const { return Edge(use_, input_ptr_); } | 440 Edge operator*() const { return Edge(use_, input_ptr_); } |
403 bool operator==(const iterator& other) const { | 441 bool operator==(const iterator& other) const { |
404 return input_ptr_ == other.input_ptr_; | 442 return input_ptr_ == other.input_ptr_; |
405 } | 443 } |
406 bool operator!=(const iterator& other) const { return !(*this == other); } | 444 bool operator!=(const iterator& other) const { return !(*this == other); } |
407 iterator& operator++() { | 445 iterator& operator++() { |
408 input_ptr_++; | 446 input_ptr_++; |
409 use_--; | 447 use_--; |
410 return *this; | 448 return *this; |
411 } | 449 } |
412 iterator operator++(int); | 450 iterator operator++(int); |
413 iterator& operator+=(difference_type offset) { | 451 iterator& operator+=(difference_type offset) { |
414 input_ptr_ += offset; | 452 input_ptr_ += offset; |
415 use_ -= offset; | 453 use_ -= offset; |
416 return *this; | 454 return *this; |
417 } | 455 } |
418 iterator operator+(difference_type offset) const { | 456 iterator operator+(difference_type offset) const { |
419 return iterator(use_ - offset, input_ptr_ + offset); | 457 return iterator(use_ - offset, input_ptr_ + offset); |
420 } | 458 } |
421 difference_type operator-(const iterator& other) const { | 459 difference_type operator-(const iterator& other) const { |
422 return static_cast<difference_type>(input_ptr_ - other.input_ptr_); | 460 return input_ptr_ - other.input_ptr_; |
423 } | 461 } |
424 | 462 |
425 private: | 463 private: |
426 friend class Node; | 464 friend class Node; |
427 | 465 |
428 explicit iterator(Node* from, int index = 0) | |
429 : use_(from->GetUsePtr(index)), input_ptr_(from->GetInputPtr(index)) {} | |
430 | |
431 explicit iterator(Use* use, Node** input_ptr) | 466 explicit iterator(Use* use, Node** input_ptr) |
432 : use_(use), input_ptr_(input_ptr) {} | 467 : use_(use), input_ptr_(input_ptr) {} |
433 | 468 |
434 Use* use_; | 469 Use* use_; |
435 Node** input_ptr_; | 470 Node** input_ptr_; |
436 }; | 471 }; |
437 | 472 |
438 | 473 |
439 Node::InputEdges::iterator Node::InputEdges::begin() const { | 474 Node::InputEdges::iterator Node::InputEdges::begin() const { |
440 return Node::InputEdges::iterator(this->node_, 0); | 475 return Node::InputEdges::iterator(use_root_, input_root_); |
441 } | 476 } |
442 | 477 |
443 | 478 |
444 Node::InputEdges::iterator Node::InputEdges::end() const { | 479 Node::InputEdges::iterator Node::InputEdges::end() const { |
445 return Node::InputEdges::iterator(this->node_, this->node_->InputCount()); | 480 return Node::InputEdges::iterator(use_root_ - count_, input_root_ + count_); |
446 } | 481 } |
447 | 482 |
| 483 Edge Node::InputEdges::operator[](int index) const { |
| 484 return Edge(use_root_ + index, input_root_ + index); |
| 485 } |
448 | 486 |
449 // A forward iterator to visit the inputs of a node. | 487 // A forward iterator to visit the inputs of a node. |
450 class Node::Inputs::const_iterator final { | 488 class Node::Inputs::const_iterator final { |
451 public: | 489 public: |
452 typedef std::forward_iterator_tag iterator_category; | 490 typedef std::forward_iterator_tag iterator_category; |
453 typedef int difference_type; | 491 typedef std::ptrdiff_t difference_type; |
454 typedef Node* value_type; | 492 typedef Node* value_type; |
455 typedef Node** pointer; | 493 typedef const value_type* pointer; |
456 typedef Node*& reference; | 494 typedef value_type& reference; |
457 | 495 |
458 const_iterator(const const_iterator& other) : iter_(other.iter_) {} | 496 const_iterator(const const_iterator& other) : input_ptr_(other.input_ptr_) {} |
459 | 497 |
460 Node* operator*() const { return (*iter_).to(); } | 498 Node* operator*() const { return *input_ptr_; } |
461 bool operator==(const const_iterator& other) const { | 499 bool operator==(const const_iterator& other) const { |
462 return iter_ == other.iter_; | 500 return input_ptr_ == other.input_ptr_; |
463 } | 501 } |
464 bool operator!=(const const_iterator& other) const { | 502 bool operator!=(const const_iterator& other) const { |
465 return !(*this == other); | 503 return !(*this == other); |
466 } | 504 } |
467 const_iterator& operator++() { | 505 const_iterator& operator++() { |
468 ++iter_; | 506 ++input_ptr_; |
469 return *this; | 507 return *this; |
470 } | 508 } |
471 const_iterator operator++(int); | 509 const_iterator operator++(int); |
472 const_iterator& operator+=(difference_type offset) { | 510 const_iterator& operator+=(difference_type offset) { |
473 iter_ += offset; | 511 input_ptr_ += offset; |
474 return *this; | 512 return *this; |
475 } | 513 } |
476 const_iterator operator+(difference_type offset) const { | 514 const_iterator operator+(difference_type offset) const { |
477 return const_iterator(iter_ + offset); | 515 return const_iterator(input_ptr_ + offset); |
478 } | 516 } |
479 difference_type operator-(const const_iterator& other) const { | 517 difference_type operator-(const const_iterator& other) const { |
480 return iter_ - other.iter_; | 518 return input_ptr_ - other.input_ptr_; |
481 } | 519 } |
482 | 520 |
483 private: | 521 private: |
484 friend class Node::Inputs; | 522 friend class Node::Inputs; |
485 | 523 |
486 const_iterator(Node* node, int index) : iter_(node, index) {} | 524 explicit const_iterator(Node* const* input_ptr) : input_ptr_(input_ptr) {} |
487 | 525 |
488 explicit const_iterator(Node::InputEdges::iterator iter) : iter_(iter) {} | 526 Node* const* input_ptr_; |
489 | |
490 Node::InputEdges::iterator iter_; | |
491 }; | 527 }; |
492 | 528 |
493 | 529 |
494 Node::Inputs::const_iterator Node::Inputs::begin() const { | 530 Node::Inputs::const_iterator Node::Inputs::begin() const { |
495 return const_iterator(this->node_, 0); | 531 return const_iterator(input_root_); |
496 } | 532 } |
497 | 533 |
498 | 534 |
499 Node::Inputs::const_iterator Node::Inputs::end() const { | 535 Node::Inputs::const_iterator Node::Inputs::end() const { |
500 return const_iterator(this->node_, this->node_->InputCount()); | 536 return const_iterator(input_root_ + count_); |
501 } | 537 } |
502 | 538 |
| 539 Node* Node::Inputs::operator[](int index) const { return input_root_[index]; } |
503 | 540 |
504 // A forward iterator to visit the uses edges of a node. | 541 // A forward iterator to visit the uses edges of a node. |
505 class Node::UseEdges::iterator final { | 542 class Node::UseEdges::iterator final { |
506 public: | 543 public: |
507 iterator(const iterator& other) | 544 iterator(const iterator& other) |
508 : current_(other.current_), next_(other.next_) {} | 545 : current_(other.current_), next_(other.next_) {} |
509 | 546 |
510 Edge operator*() const { return Edge(current_, current_->input_ptr()); } | 547 Edge operator*() const { return Edge(current_, current_->input_ptr()); } |
511 bool operator==(const iterator& other) const { | 548 bool operator==(const iterator& other) const { |
512 return current_ == other.current_; | 549 return current_ == other.current_; |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
583 } | 620 } |
584 | 621 |
585 | 622 |
586 Node::Uses::const_iterator Node::Uses::end() const { return const_iterator(); } | 623 Node::Uses::const_iterator Node::Uses::end() const { return const_iterator(); } |
587 | 624 |
588 } // namespace compiler | 625 } // namespace compiler |
589 } // namespace internal | 626 } // namespace internal |
590 } // namespace v8 | 627 } // namespace v8 |
591 | 628 |
592 #endif // V8_COMPILER_NODE_H_ | 629 #endif // V8_COMPILER_NODE_H_ |
OLD | NEW |