| 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/types-inl.h" | 10 #include "src/types-inl.h" |
| (...skipping 21 matching lines...) Expand all Loading... |
| 32 | 32 |
| 33 // A Node is the basic primitive of graphs. Nodes are chained together by | 33 // A Node is the basic primitive of graphs. Nodes are chained together by |
| 34 // input/use chains but by default otherwise contain only an identifying number | 34 // input/use chains but by default otherwise contain only an identifying number |
| 35 // which specific applications of graphs and nodes can use to index auxiliary | 35 // which specific applications of graphs and nodes can use to index auxiliary |
| 36 // out-of-line data, especially transient data. | 36 // out-of-line data, especially transient data. |
| 37 // | 37 // |
| 38 // In addition Nodes only contain a mutable Operator that may change during | 38 // In addition Nodes only contain a mutable Operator that may change during |
| 39 // compilation, e.g. during lowering passes. Other information that needs to be | 39 // compilation, e.g. during lowering passes. Other information that needs to be |
| 40 // associated with Nodes during compilation must be stored out-of-line indexed | 40 // associated with Nodes during compilation must be stored out-of-line indexed |
| 41 // by the Node's id. | 41 // by the Node's id. |
| 42 class Node FINAL { | 42 class Node final { |
| 43 public: | 43 public: |
| 44 static Node* New(Zone* zone, NodeId id, const Operator* op, int input_count, | 44 static Node* New(Zone* zone, NodeId id, const Operator* op, int input_count, |
| 45 Node** inputs, bool has_extensible_inputs); | 45 Node** inputs, bool has_extensible_inputs); |
| 46 | 46 |
| 47 bool IsDead() const { return InputCount() > 0 && !InputAt(0); } | 47 bool IsDead() const { return InputCount() > 0 && !InputAt(0); } |
| 48 void Kill(); | 48 void Kill(); |
| 49 | 49 |
| 50 const Operator* op() const { return op_; } | 50 const Operator* op() const { return op_; } |
| 51 void set_op(const Operator* op) { op_ = op; } | 51 void set_op(const Operator* op) { op_ = op; } |
| 52 | 52 |
| 53 IrOpcode::Value opcode() const { | 53 IrOpcode::Value opcode() const { |
| 54 DCHECK(op_->opcode() <= IrOpcode::kLast); | 54 DCHECK(op_->opcode() <= IrOpcode::kLast); |
| 55 return static_cast<IrOpcode::Value>(op_->opcode()); | 55 return static_cast<IrOpcode::Value>(op_->opcode()); |
| 56 } | 56 } |
| 57 | 57 |
| 58 NodeId id() const { return id_; } | 58 NodeId id() const { return id_; } |
| 59 | 59 |
| 60 int InputCount() const { return input_count(); } | 60 int InputCount() const { return input_count(); } |
| 61 Node* InputAt(int index) const { return GetInputRecordPtr(index)->to; } | 61 Node* InputAt(int index) const { return GetInputRecordPtr(index)->to; } |
| 62 inline void ReplaceInput(int index, Node* new_to); | 62 inline void ReplaceInput(int index, Node* new_to); |
| 63 void AppendInput(Zone* zone, Node* new_to); | 63 void AppendInput(Zone* zone, Node* new_to); |
| 64 void InsertInput(Zone* zone, int index, Node* new_to); | 64 void InsertInput(Zone* zone, int index, Node* new_to); |
| 65 void RemoveInput(int index); | 65 void RemoveInput(int index); |
| 66 void NullAllInputs(); | 66 void NullAllInputs(); |
| 67 void TrimInputCount(int new_input_count); | 67 void TrimInputCount(int new_input_count); |
| 68 | 68 |
| 69 int UseCount() const; | 69 int UseCount() const; |
| 70 void ReplaceUses(Node* replace_to); | 70 void ReplaceUses(Node* replace_to); |
| 71 | 71 |
| 72 class InputEdges FINAL { | 72 class InputEdges final { |
| 73 public: | 73 public: |
| 74 typedef Edge value_type; | 74 typedef Edge value_type; |
| 75 | 75 |
| 76 class iterator; | 76 class iterator; |
| 77 inline iterator begin() const; | 77 inline iterator begin() const; |
| 78 inline iterator end() const; | 78 inline iterator end() const; |
| 79 | 79 |
| 80 bool empty() const; | 80 bool empty() const; |
| 81 | 81 |
| 82 explicit InputEdges(Node* node) : node_(node) {} | 82 explicit InputEdges(Node* node) : node_(node) {} |
| 83 | 83 |
| 84 private: | 84 private: |
| 85 Node* node_; | 85 Node* node_; |
| 86 }; | 86 }; |
| 87 | 87 |
| 88 InputEdges input_edges() { return InputEdges(this); } | 88 InputEdges input_edges() { return InputEdges(this); } |
| 89 | 89 |
| 90 class Inputs FINAL { | 90 class Inputs final { |
| 91 public: | 91 public: |
| 92 typedef Node* value_type; | 92 typedef Node* value_type; |
| 93 | 93 |
| 94 class const_iterator; | 94 class const_iterator; |
| 95 inline const_iterator begin() const; | 95 inline const_iterator begin() const; |
| 96 inline const_iterator end() const; | 96 inline const_iterator end() const; |
| 97 | 97 |
| 98 bool empty() const; | 98 bool empty() const; |
| 99 | 99 |
| 100 explicit Inputs(Node* node) : node_(node) {} | 100 explicit Inputs(Node* node) : node_(node) {} |
| 101 | 101 |
| 102 private: | 102 private: |
| 103 Node* node_; | 103 Node* node_; |
| 104 }; | 104 }; |
| 105 | 105 |
| 106 Inputs inputs() { return Inputs(this); } | 106 Inputs inputs() { return Inputs(this); } |
| 107 | 107 |
| 108 class UseEdges FINAL { | 108 class UseEdges final { |
| 109 public: | 109 public: |
| 110 typedef Edge value_type; | 110 typedef Edge value_type; |
| 111 | 111 |
| 112 class iterator; | 112 class iterator; |
| 113 inline iterator begin() const; | 113 inline iterator begin() const; |
| 114 inline iterator end() const; | 114 inline iterator end() const; |
| 115 | 115 |
| 116 bool empty() const; | 116 bool empty() const; |
| 117 | 117 |
| 118 explicit UseEdges(Node* node) : node_(node) {} | 118 explicit UseEdges(Node* node) : node_(node) {} |
| 119 | 119 |
| 120 private: | 120 private: |
| 121 Node* node_; | 121 Node* node_; |
| 122 }; | 122 }; |
| 123 | 123 |
| 124 UseEdges use_edges() { return UseEdges(this); } | 124 UseEdges use_edges() { return UseEdges(this); } |
| 125 | 125 |
| 126 class Uses FINAL { | 126 class Uses final { |
| 127 public: | 127 public: |
| 128 typedef Node* value_type; | 128 typedef Node* value_type; |
| 129 | 129 |
| 130 class const_iterator; | 130 class const_iterator; |
| 131 inline const_iterator begin() const; | 131 inline const_iterator begin() const; |
| 132 inline const_iterator end() const; | 132 inline const_iterator end() const; |
| 133 | 133 |
| 134 bool empty() const; | 134 bool empty() const; |
| 135 | 135 |
| 136 explicit Uses(Node* node) : node_(node) {} | 136 explicit Uses(Node* node) : node_(node) {} |
| 137 | 137 |
| 138 private: | 138 private: |
| 139 Node* node_; | 139 Node* node_; |
| 140 }; | 140 }; |
| 141 | 141 |
| 142 Uses uses() { return Uses(this); } | 142 Uses uses() { return Uses(this); } |
| 143 | 143 |
| 144 // Returns true if {owner} is the user of {this} node. | 144 // Returns true if {owner} is the user of {this} node. |
| 145 bool OwnedBy(Node* owner) const { | 145 bool OwnedBy(Node* owner) const { |
| 146 return first_use_ && first_use_->from == owner && !first_use_->next; | 146 return first_use_ && first_use_->from == owner && !first_use_->next; |
| 147 } | 147 } |
| 148 | 148 |
| 149 private: | 149 private: |
| 150 struct Use FINAL : public ZoneObject { | 150 struct Use final : public ZoneObject { |
| 151 Node* from; | 151 Node* from; |
| 152 Use* next; | 152 Use* next; |
| 153 Use* prev; | 153 Use* prev; |
| 154 int input_index; | 154 int input_index; |
| 155 }; | 155 }; |
| 156 | 156 |
| 157 class Input FINAL { | 157 class Input final { |
| 158 public: | 158 public: |
| 159 Node* to; | 159 Node* to; |
| 160 Use* use; | 160 Use* use; |
| 161 | 161 |
| 162 void Update(Node* new_to); | 162 void Update(Node* new_to); |
| 163 }; | 163 }; |
| 164 | 164 |
| 165 inline Node(NodeId id, const Operator* op, int input_count, | 165 inline Node(NodeId id, const Operator* op, int input_count, |
| 166 int reserve_input_count); | 166 int reserve_input_count); |
| 167 | 167 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 // Helper to extract parameters from Operator1<*> nodes. | 255 // Helper to extract parameters from Operator1<*> nodes. |
| 256 template <typename T> | 256 template <typename T> |
| 257 static inline const T& OpParameter(const Node* node) { | 257 static inline const T& OpParameter(const Node* node) { |
| 258 return OpParameter<T>(node->op()); | 258 return OpParameter<T>(node->op()); |
| 259 } | 259 } |
| 260 | 260 |
| 261 | 261 |
| 262 // An encapsulation for information associated with a single use of node as a | 262 // An encapsulation for information associated with a single use of node as a |
| 263 // input from another node, allowing access to both the defining node and | 263 // input from another node, allowing access to both the defining node and |
| 264 // the node having the input. | 264 // the node having the input. |
| 265 class Edge FINAL { | 265 class Edge final { |
| 266 public: | 266 public: |
| 267 Node* from() const { return input_->use->from; } | 267 Node* from() const { return input_->use->from; } |
| 268 Node* to() const { return input_->to; } | 268 Node* to() const { return input_->to; } |
| 269 int index() const { | 269 int index() const { |
| 270 int const index = input_->use->input_index; | 270 int const index = input_->use->input_index; |
| 271 DCHECK_LT(index, input_->use->from->input_count()); | 271 DCHECK_LT(index, input_->use->from->input_count()); |
| 272 return index; | 272 return index; |
| 273 } | 273 } |
| 274 | 274 |
| 275 bool operator==(const Edge& other) { return input_ == other.input_; } | 275 bool operator==(const Edge& other) { return input_ == other.input_; } |
| 276 bool operator!=(const Edge& other) { return !(*this == other); } | 276 bool operator!=(const Edge& other) { return !(*this == other); } |
| 277 | 277 |
| 278 void UpdateTo(Node* new_to) { input_->Update(new_to); } | 278 void UpdateTo(Node* new_to) { input_->Update(new_to); } |
| 279 | 279 |
| 280 private: | 280 private: |
| 281 friend class Node::UseEdges::iterator; | 281 friend class Node::UseEdges::iterator; |
| 282 friend class Node::InputEdges::iterator; | 282 friend class Node::InputEdges::iterator; |
| 283 | 283 |
| 284 explicit Edge(Node::Input* input) : input_(input) { DCHECK_NOT_NULL(input); } | 284 explicit Edge(Node::Input* input) : input_(input) { DCHECK_NOT_NULL(input); } |
| 285 | 285 |
| 286 Node::Input* input_; | 286 Node::Input* input_; |
| 287 }; | 287 }; |
| 288 | 288 |
| 289 | 289 |
| 290 // A forward iterator to visit the edges for the input dependencies of a node. | 290 // A forward iterator to visit the edges for the input dependencies of a node. |
| 291 class Node::InputEdges::iterator FINAL { | 291 class Node::InputEdges::iterator final { |
| 292 public: | 292 public: |
| 293 typedef std::forward_iterator_tag iterator_category; | 293 typedef std::forward_iterator_tag iterator_category; |
| 294 typedef int difference_type; | 294 typedef int difference_type; |
| 295 typedef Edge value_type; | 295 typedef Edge value_type; |
| 296 typedef Edge* pointer; | 296 typedef Edge* pointer; |
| 297 typedef Edge& reference; | 297 typedef Edge& reference; |
| 298 | 298 |
| 299 iterator() : input_(nullptr) {} | 299 iterator() : input_(nullptr) {} |
| 300 iterator(const iterator& other) : input_(other.input_) {} | 300 iterator(const iterator& other) : input_(other.input_) {} |
| 301 | 301 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 return Node::InputEdges::iterator(this->node_, 0); | 334 return Node::InputEdges::iterator(this->node_, 0); |
| 335 } | 335 } |
| 336 | 336 |
| 337 | 337 |
| 338 Node::InputEdges::iterator Node::InputEdges::end() const { | 338 Node::InputEdges::iterator Node::InputEdges::end() const { |
| 339 return Node::InputEdges::iterator(this->node_, this->node_->InputCount()); | 339 return Node::InputEdges::iterator(this->node_, this->node_->InputCount()); |
| 340 } | 340 } |
| 341 | 341 |
| 342 | 342 |
| 343 // A forward iterator to visit the inputs of a node. | 343 // A forward iterator to visit the inputs of a node. |
| 344 class Node::Inputs::const_iterator FINAL { | 344 class Node::Inputs::const_iterator final { |
| 345 public: | 345 public: |
| 346 typedef std::forward_iterator_tag iterator_category; | 346 typedef std::forward_iterator_tag iterator_category; |
| 347 typedef int difference_type; | 347 typedef int difference_type; |
| 348 typedef Node* value_type; | 348 typedef Node* value_type; |
| 349 typedef Node** pointer; | 349 typedef Node** pointer; |
| 350 typedef Node*& reference; | 350 typedef Node*& reference; |
| 351 | 351 |
| 352 const_iterator(const const_iterator& other) : iter_(other.iter_) {} | 352 const_iterator(const const_iterator& other) : iter_(other.iter_) {} |
| 353 | 353 |
| 354 Node* operator*() const { return (*iter_).to(); } | 354 Node* operator*() const { return (*iter_).to(); } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 379 | 379 |
| 380 | 380 |
| 381 Node::Inputs::const_iterator Node::Inputs::end() const { | 381 Node::Inputs::const_iterator Node::Inputs::end() const { |
| 382 return const_iterator(this->node_, this->node_->InputCount()); | 382 return const_iterator(this->node_, this->node_->InputCount()); |
| 383 } | 383 } |
| 384 | 384 |
| 385 | 385 |
| 386 // A forward iterator to visit the uses edges of a node. The edges are returned | 386 // A forward iterator to visit the uses edges of a node. The edges are returned |
| 387 // in | 387 // in |
| 388 // the order in which they were added as inputs. | 388 // the order in which they were added as inputs. |
| 389 class Node::UseEdges::iterator FINAL { | 389 class Node::UseEdges::iterator final { |
| 390 public: | 390 public: |
| 391 iterator(const iterator& other) | 391 iterator(const iterator& other) |
| 392 : current_(other.current_), next_(other.next_) {} | 392 : current_(other.current_), next_(other.next_) {} |
| 393 | 393 |
| 394 Edge operator*() const { | 394 Edge operator*() const { |
| 395 return Edge(current_->from->GetInputRecordPtr(current_->input_index)); | 395 return Edge(current_->from->GetInputRecordPtr(current_->input_index)); |
| 396 } | 396 } |
| 397 | 397 |
| 398 bool operator==(const iterator& other) const { | 398 bool operator==(const iterator& other) const { |
| 399 return current_ == other.current_; | 399 return current_ == other.current_; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 425 } | 425 } |
| 426 | 426 |
| 427 | 427 |
| 428 Node::UseEdges::iterator Node::UseEdges::end() const { | 428 Node::UseEdges::iterator Node::UseEdges::end() const { |
| 429 return Node::UseEdges::iterator(); | 429 return Node::UseEdges::iterator(); |
| 430 } | 430 } |
| 431 | 431 |
| 432 | 432 |
| 433 // A forward iterator to visit the uses of a node. The uses are returned in | 433 // A forward iterator to visit the uses of a node. The uses are returned in |
| 434 // the order in which they were added as inputs. | 434 // the order in which they were added as inputs. |
| 435 class Node::Uses::const_iterator FINAL { | 435 class Node::Uses::const_iterator final { |
| 436 public: | 436 public: |
| 437 typedef std::forward_iterator_tag iterator_category; | 437 typedef std::forward_iterator_tag iterator_category; |
| 438 typedef int difference_type; | 438 typedef int difference_type; |
| 439 typedef Node* value_type; | 439 typedef Node* value_type; |
| 440 typedef Node** pointer; | 440 typedef Node** pointer; |
| 441 typedef Node*& reference; | 441 typedef Node*& reference; |
| 442 | 442 |
| 443 const_iterator(const const_iterator& other) : current_(other.current_) {} | 443 const_iterator(const const_iterator& other) : current_(other.current_) {} |
| 444 | 444 |
| 445 Node* operator*() const { return current_->from; } | 445 Node* operator*() const { return current_->from; } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 476 | 476 |
| 477 void Node::ReplaceInput(int index, Node* new_to) { | 477 void Node::ReplaceInput(int index, Node* new_to) { |
| 478 GetInputRecordPtr(index)->Update(new_to); | 478 GetInputRecordPtr(index)->Update(new_to); |
| 479 } | 479 } |
| 480 | 480 |
| 481 } // namespace compiler | 481 } // namespace compiler |
| 482 } // namespace internal | 482 } // namespace internal |
| 483 } // namespace v8 | 483 } // namespace v8 |
| 484 | 484 |
| 485 #endif // V8_COMPILER_NODE_H_ | 485 #endif // V8_COMPILER_NODE_H_ |
| OLD | NEW |