Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1300)

Side by Side Diff: src/compiler/node.h

Issue 851263002: [turbofan] Initial attempt to cleanup Node and related classes. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/mips64/instruction-selector-mips64.cc ('k') | src/compiler/node.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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>
9 #include <vector>
10
11 #include "src/compiler/opcodes.h" 8 #include "src/compiler/opcodes.h"
12 #include "src/compiler/operator.h" 9 #include "src/compiler/operator.h"
13 #include "src/types-inl.h" 10 #include "src/types-inl.h"
14 #include "src/zone.h"
15 #include "src/zone-allocator.h"
16 #include "src/zone-containers.h" 11 #include "src/zone-containers.h"
17 12
18 namespace v8 { 13 namespace v8 {
19 namespace internal { 14 namespace internal {
20 namespace compiler { 15 namespace compiler {
21 16
22 // Forward declarations. 17 // Forward declarations.
23 class Edge; 18 class Edge;
24 class Graph; 19 class Graph;
25 20
(...skipping 13 matching lines...) Expand all
39 // 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
40 // 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
41 // out-of-line data, especially transient data. 36 // out-of-line data, especially transient data.
42 // 37 //
43 // 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
44 // 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
45 // 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
46 // by the Node's id. 41 // by the Node's id.
47 class Node FINAL { 42 class Node FINAL {
48 public: 43 public:
49 bool IsDead() const { return InputCount() > 0 && InputAt(0) == NULL; } 44 static Node* New(Zone* zone, NodeId id, const Operator* op, int input_count,
45 Node** inputs, bool has_extensible_inputs);
46
47 bool IsDead() const { return InputCount() > 0 && !InputAt(0); }
50 void Kill(); 48 void Kill();
51 49
52 void CollectProjections(ZoneVector<Node*>* projections);
53 Node* FindProjection(size_t projection_index);
54
55 const Operator* op() const { return op_; } 50 const Operator* op() const { return op_; }
56 void set_op(const Operator* op) { op_ = op; } 51 void set_op(const Operator* op) { op_ = op; }
57 52
58 IrOpcode::Value opcode() const { 53 IrOpcode::Value opcode() const {
59 DCHECK(op_->opcode() <= IrOpcode::kLast); 54 DCHECK(op_->opcode() <= IrOpcode::kLast);
60 return static_cast<IrOpcode::Value>(op_->opcode()); 55 return static_cast<IrOpcode::Value>(op_->opcode());
61 } 56 }
62 57
63 NodeId id() const { return id_; } 58 NodeId id() const { return id_; }
64 59
65 int InputCount() const { return input_count(); } 60 int InputCount() const { return input_count(); }
66 Node* InputAt(int index) const { return GetInputRecordPtr(index)->to; } 61 Node* InputAt(int index) const { return GetInputRecordPtr(index)->to; }
67 inline void ReplaceInput(int index, Node* new_input); 62 inline void ReplaceInput(int index, Node* new_to);
68 inline void AppendInput(Zone* zone, Node* new_input); 63 void AppendInput(Zone* zone, Node* new_to);
69 inline void InsertInput(Zone* zone, int index, Node* new_input); 64 void InsertInput(Zone* zone, int index, Node* new_to);
70 inline void RemoveInput(int index); 65 void RemoveInput(int index);
66 void RemoveAllInputs();
67 void TrimInputCount(int new_input_count);
71 68
72 int UseCount() const; 69 int UseCount() const;
73 Node* UseAt(int index) const; 70 Node* UseAt(int index) const;
74 inline void ReplaceUses(Node* replace_to); 71 void ReplaceUses(Node* replace_to);
75 template <class UnaryPredicate>
76 inline void ReplaceUsesIf(UnaryPredicate pred, Node* replace_to);
77 inline void RemoveAllInputs();
78 72
79 inline void TrimInputCount(int input_count); 73 class InputEdges FINAL {
74 public:
75 typedef Edge value_type;
80 76
81 class InputEdges {
82 public:
83 class iterator; 77 class iterator;
84 iterator begin() const; 78 inline iterator begin() const;
85 iterator end() const; 79 inline iterator end() const;
80
86 bool empty() const; 81 bool empty() const;
87 82
88 explicit InputEdges(Node* node) : node_(node) {} 83 explicit InputEdges(Node* node) : node_(node) {}
89 84
90 private: 85 private:
91 Node* node_; 86 Node* node_;
92 }; 87 };
93 88
94 class Inputs { 89 InputEdges input_edges() { return InputEdges(this); }
90
91 class Inputs FINAL {
95 public: 92 public:
96 class iterator; 93 typedef Node* value_type;
97 iterator begin() const; 94
98 iterator end() const; 95 class const_iterator;
96 inline const_iterator begin() const;
97 inline const_iterator end() const;
98
99 bool empty() const; 99 bool empty() const;
100 100
101 explicit Inputs(Node* node) : node_(node) {} 101 explicit Inputs(Node* node) : node_(node) {}
102 102
103 private: 103 private:
104 Node* node_; 104 Node* node_;
105 }; 105 };
106 106
107 Inputs inputs() { return Inputs(this); } 107 Inputs inputs() { return Inputs(this); }
108 InputEdges input_edges() { return InputEdges(this); }
109 108
110 class UseEdges { 109 class UseEdges FINAL {
111 public: 110 public:
111 typedef Edge value_type;
112
112 class iterator; 113 class iterator;
113 iterator begin() const; 114 inline iterator begin() const;
114 iterator end() const; 115 inline iterator end() const;
116
115 bool empty() const; 117 bool empty() const;
116 118
117 explicit UseEdges(Node* node) : node_(node) {} 119 explicit UseEdges(Node* node) : node_(node) {}
118 120
119 private: 121 private:
120 Node* node_; 122 Node* node_;
121 }; 123 };
122 124
123 class Uses { 125 UseEdges use_edges() { return UseEdges(this); }
126
127 class Uses FINAL {
124 public: 128 public:
125 class iterator; 129 typedef Node* value_type;
126 iterator begin() const; 130
127 iterator end() const; 131 class const_iterator;
132 inline const_iterator begin() const;
133 inline const_iterator end() const;
134
128 bool empty() const; 135 bool empty() const;
129 136
130 explicit Uses(Node* node) : node_(node) {} 137 explicit Uses(Node* node) : node_(node) {}
131 138
132 private: 139 private:
133 Node* node_; 140 Node* node_;
134 }; 141 };
135 142
136 Uses uses() { return Uses(this); } 143 Uses uses() { return Uses(this); }
137 UseEdges use_edges() { return UseEdges(this); }
138 144
139 bool OwnedBy(Node* owner) const; 145 // Returns true if {owner} is the user of {this} node.
146 bool OwnedBy(Node* owner) const {
147 return first_use_ && first_use_->from == owner && !first_use_->next;
148 }
140 149
141 static Node* New(Zone* zone, NodeId id, const Operator* op, int input_count, 150 private:
142 Node** inputs, bool has_extensible_inputs); 151 struct Use FINAL : public ZoneObject {
143
144 protected:
145 friend class Graph;
146 friend class Edge;
147
148 class Use : public ZoneObject {
149 public:
150 Node* from; 152 Node* from;
151 Use* next; 153 Use* next;
152 Use* prev; 154 Use* prev;
153 int input_index; 155 int input_index;
154 }; 156 };
155 157
156 class Input { 158 class Input FINAL {
157 public: 159 public:
158 Node* to; 160 Node* to;
159 Use* use; 161 Use* use;
160 162
161 void Update(Node* new_to); 163 void Update(Node* new_to);
162 }; 164 };
163 165
164 void EnsureAppendableInputs(Zone* zone); 166 inline Node(NodeId id, const Operator* op, int input_count,
167 int reserve_input_count);
168
169 inline void EnsureAppendableInputs(Zone* zone);
165 170
166 Input* GetInputRecordPtr(int index) const { 171 Input* GetInputRecordPtr(int index) const {
167 if (has_appendable_inputs()) { 172 if (has_appendable_inputs()) {
168 return &((*inputs_.appendable_)[index]); 173 return &((*inputs_.appendable_)[index]);
169 } else { 174 } else {
170 return &inputs_.static_[index]; 175 return &inputs_.static_[index];
171 } 176 }
172 } 177 }
173 178
174 inline void AppendUse(Use* use); 179 inline void AppendUse(Use* const use);
175 inline void RemoveUse(Use* use); 180 inline void RemoveUse(Use* const use);
176 181
177 void* operator new(size_t, void* location) { return location; } 182 void* operator new(size_t, void* location) { return location; }
178 183
179 private:
180 inline Node(NodeId id, const Operator* op, int input_count,
181 int reserve_input_count);
182
183 typedef ZoneDeque<Input> InputDeque; 184 typedef ZoneDeque<Input> InputDeque;
184 185
185 friend class NodeMarkerBase;
186 friend class NodeProperties;
187
188 // Only NodeProperties should manipulate the bounds. 186 // Only NodeProperties should manipulate the bounds.
189 Bounds bounds() { return bounds_; } 187 Bounds bounds() { return bounds_; }
190 void set_bounds(Bounds b) { bounds_ = b; } 188 void set_bounds(Bounds b) { bounds_ = b; }
191 189
192 // Only NodeMarkers should manipulate the marks on nodes. 190 // Only NodeMarkers should manipulate the marks on nodes.
193 Mark mark() { return mark_; } 191 Mark mark() { return mark_; }
194 void set_mark(Mark mark) { mark_ = mark; } 192 void set_mark(Mark mark) { mark_ = mark; }
195 193
196 int input_count() const { return InputCountField::decode(bit_field_); } 194 int input_count() const { return InputCountField::decode(bit_field_); }
197 void set_input_count(int input_count) { 195 void set_input_count(int input_count) {
(...skipping 19 matching lines...) Expand all
217 } 215 }
218 216
219 typedef BitField<unsigned, 0, 29> InputCountField; 217 typedef BitField<unsigned, 0, 29> InputCountField;
220 typedef BitField<unsigned, 29, 2> ReservedInputCountField; 218 typedef BitField<unsigned, 29, 2> ReservedInputCountField;
221 typedef BitField<unsigned, 31, 1> HasAppendableInputsField; 219 typedef BitField<unsigned, 31, 1> HasAppendableInputsField;
222 static const int kDefaultReservedInputs = ReservedInputCountField::kMax; 220 static const int kDefaultReservedInputs = ReservedInputCountField::kMax;
223 221
224 const Operator* op_; 222 const Operator* op_;
225 Bounds bounds_; 223 Bounds bounds_;
226 Mark mark_; 224 Mark mark_;
227 NodeId id_; 225 NodeId const id_;
228 unsigned bit_field_; 226 unsigned bit_field_;
229 union { 227 union {
230 // When a node is initially allocated, it uses a static buffer to hold its 228 // When a node is initially allocated, it uses a static buffer to hold its
231 // inputs under the assumption that the number of outputs will not increase. 229 // inputs under the assumption that the number of outputs will not increase.
232 // When the first input is appended, the static buffer is converted into a 230 // When the first input is appended, the static buffer is converted into a
233 // deque to allow for space-efficient growing. 231 // deque to allow for space-efficient growing.
234 Input* static_; 232 Input* static_;
235 InputDeque* appendable_; 233 InputDeque* appendable_;
236 } inputs_; 234 } inputs_;
237 Use* first_use_; 235 Use* first_use_;
238 Use* last_use_; 236 Use* last_use_;
239 237
238 friend class Edge;
239 friend class NodeMarkerBase;
240 friend class NodeProperties;
241
240 DISALLOW_COPY_AND_ASSIGN(Node); 242 DISALLOW_COPY_AND_ASSIGN(Node);
241 }; 243 };
242 244
243 245
246 std::ostream& operator<<(std::ostream& os, const Node& n);
247
248
249 // Typedefs to shorten commonly used Node containers.
250 typedef ZoneDeque<Node*> NodeDeque;
251 typedef ZoneVector<Node*> NodeVector;
252 typedef ZoneVector<NodeVector> NodeVectorVector;
253
254
255 // Helper to extract parameters from Operator1<*> nodes.
256 template <typename T>
257 static inline const T& OpParameter(const Node* node) {
258 return OpParameter<T>(node->op());
259 }
260
261
244 // 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
245 // 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
246 // the node having the input. 264 // the node having the input.
247 class Edge { 265 class Edge FINAL {
248 public: 266 public:
249 Node* from() const { return input_->use->from; } 267 Node* from() const { return input_->use->from; }
250 Node* to() const { return input_->to; } 268 Node* to() const { return input_->to; }
251 int index() const { 269 int index() const {
252 int index = input_->use->input_index; 270 int const index = input_->use->input_index;
253 DCHECK(index < input_->use->from->input_count()); 271 DCHECK_LT(index, input_->use->from->input_count());
254 return index; 272 return index;
255 } 273 }
256 274
257 bool operator==(const Edge& other) { return input_ == other.input_; } 275 bool operator==(const Edge& other) { return input_ == other.input_; }
258 bool operator!=(const Edge& other) { return !(*this == other); } 276 bool operator!=(const Edge& other) { return !(*this == other); }
259 277
260 void UpdateTo(Node* new_to) { input_->Update(new_to); } 278 void UpdateTo(Node* new_to) { input_->Update(new_to); }
261 279
262 private: 280 private:
263 friend class Node::Uses::iterator;
264 friend class Node::Inputs::iterator;
265 friend class Node::UseEdges::iterator; 281 friend class Node::UseEdges::iterator;
266 friend class Node::InputEdges::iterator; 282 friend class Node::InputEdges::iterator;
267 283
268 explicit Edge(Node::Input* input) : input_(input) {} 284 explicit Edge(Node::Input* input) : input_(input) { DCHECK_NOT_NULL(input); }
269 285
270 Node::Input* input_; 286 Node::Input* const input_;
271 }; 287 };
272 288
273 289
274 // 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.
275 class Node::InputEdges::iterator { 291 class Node::InputEdges::iterator FINAL {
276 public: 292 public:
277 typedef std::forward_iterator_tag iterator_category; 293 typedef std::forward_iterator_tag iterator_category;
278 typedef int difference_type; 294 typedef int difference_type;
279 typedef Edge value_type; 295 typedef Edge value_type;
280 typedef Edge* pointer; 296 typedef Edge* pointer;
281 typedef Edge& reference; 297 typedef Edge& reference;
282 iterator(const Node::InputEdges::iterator& other) // NOLINT 298
283 : input_(other.input_) {} 299 iterator() : input_(nullptr) {}
284 iterator() : input_(NULL) {} 300 iterator(const iterator& other) : input_(other.input_) {}
285 301
286 Edge operator*() const { return Edge(input_); } 302 Edge operator*() const { return Edge(input_); }
287 bool operator==(const iterator& other) const { return Equals(other); } 303 bool operator==(const iterator& other) const {
288 bool operator!=(const iterator& other) const { return !Equals(other); } 304 return input_ == other.input_;
305 }
306 bool operator!=(const iterator& other) const { return !(*this == other); }
289 iterator& operator++() { 307 iterator& operator++() {
290 DCHECK(input_ != NULL); 308 SetInput(Edge(input_).from(), input_->use->input_index + 1);
291 Edge edge(input_);
292 Node* from = edge.from();
293 SetInput(from, input_->use->input_index + 1);
294 return *this; 309 return *this;
295 } 310 }
296 iterator operator++(int) { 311 iterator operator++(int);
297 iterator result(*this);
298 ++(*this);
299 return result;
300 }
301 312
302 private: 313 private:
303 friend class Node; 314 friend class Node;
304 315
305 explicit iterator(Node* from, int index = 0) : input_(NULL) { 316 explicit iterator(Node* from, int index = 0) : input_(nullptr) {
306 SetInput(from, index); 317 SetInput(from, index);
307 } 318 }
308 319
309 bool Equals(const iterator& other) const { return other.input_ == input_; }
310 void SetInput(Node* from, int index) { 320 void SetInput(Node* from, int index) {
311 DCHECK(index >= 0 && index <= from->InputCount()); 321 DCHECK(index >= 0 && index <= from->InputCount());
312 if (index < from->InputCount()) { 322 if (index < from->InputCount()) {
313 input_ = from->GetInputRecordPtr(index); 323 input_ = from->GetInputRecordPtr(index);
314 } else { 324 } else {
315 input_ = NULL; 325 input_ = nullptr;
316 } 326 }
317 } 327 }
318 328
319 Input* input_; 329 Input* input_;
320 }; 330 };
321 331
322 332
333 Node::InputEdges::iterator Node::InputEdges::begin() const {
334 return Node::InputEdges::iterator(this->node_, 0);
335 }
336
337
338 Node::InputEdges::iterator Node::InputEdges::end() const {
339 return Node::InputEdges::iterator(this->node_, this->node_->InputCount());
340 }
341
342
323 // A forward iterator to visit the inputs of a node. 343 // A forward iterator to visit the inputs of a node.
324 class Node::Inputs::iterator { 344 class Node::Inputs::const_iterator FINAL {
325 public: 345 public:
326 typedef std::forward_iterator_tag iterator_category; 346 typedef std::forward_iterator_tag iterator_category;
327 typedef int difference_type; 347 typedef int difference_type;
328 typedef Node* value_type; 348 typedef Node* value_type;
329 typedef Node** pointer; 349 typedef Node** pointer;
330 typedef Node*& reference; 350 typedef Node*& reference;
331 351
332 iterator(const Node::Inputs::iterator& other) // NOLINT 352 const_iterator(const const_iterator& other) : iter_(other.iter_) {}
333 : iter_(other.iter_) {}
334 353
335 Node* operator*() const { return (*iter_).to(); } 354 Node* operator*() const { return (*iter_).to(); }
336 bool operator==(const iterator& other) const { return Equals(other); } 355 bool operator==(const const_iterator& other) const {
337 bool operator!=(const iterator& other) const { return !Equals(other); } 356 return iter_ == other.iter_;
338 iterator& operator++() { 357 }
358 bool operator!=(const const_iterator& other) const {
359 return !(*this == other);
360 }
361 const_iterator& operator++() {
339 ++iter_; 362 ++iter_;
340 return *this; 363 return *this;
341 } 364 }
342 iterator operator++(int) { 365 const_iterator operator++(int);
343 iterator result(*this);
344 ++(*this);
345 return result;
346 }
347
348 366
349 private: 367 private:
350 friend class Node::Inputs; 368 friend class Node::Inputs;
351 369
352 explicit iterator(Node* node, int index) : iter_(node, index) {} 370 const_iterator(Node* node, int index) : iter_(node, index) {}
353
354 bool Equals(const iterator& other) const { return other.iter_ == iter_; }
355 371
356 Node::InputEdges::iterator iter_; 372 Node::InputEdges::iterator iter_;
357 }; 373 };
358 374
375
376 Node::Inputs::const_iterator Node::Inputs::begin() const {
377 return const_iterator(this->node_, 0);
378 }
379
380
381 Node::Inputs::const_iterator Node::Inputs::end() const {
382 return const_iterator(this->node_, this->node_->InputCount());
383 }
384
385
359 // 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
360 // in 387 // in
361 // the order in which they were added as inputs. 388 // the order in which they were added as inputs.
362 class Node::UseEdges::iterator { 389 class Node::UseEdges::iterator FINAL {
363 public: 390 public:
364 iterator(const Node::UseEdges::iterator& other) // NOLINT 391 iterator(const iterator& other)
365 : current_(other.current_), 392 : current_(other.current_), next_(other.next_) {}
366 next_(other.next_) {}
367 393
368 Edge operator*() const { return Edge(CurrentInput()); } 394 Edge operator*() const {
395 return Edge(current_->from->GetInputRecordPtr(current_->input_index));
396 }
369 397
370 bool operator==(const iterator& other) { return Equals(other); } 398 bool operator==(const iterator& other) const {
371 bool operator!=(const iterator& other) { return !Equals(other); } 399 return current_ == other.current_;
400 }
401 bool operator!=(const iterator& other) const { return !(*this == other); }
372 iterator& operator++() { 402 iterator& operator++() {
373 DCHECK(current_ != NULL); 403 DCHECK_NOT_NULL(current_);
374 current_ = next_; 404 current_ = next_;
375 next_ = (current_ == NULL) ? NULL : current_->next; 405 next_ = current_ ? current_->next : nullptr;
376 return *this; 406 return *this;
377 } 407 }
378 iterator operator++(int) { 408 iterator operator++(int);
379 iterator result(*this);
380 ++(*this);
381 return result;
382 }
383 409
384 private: 410 private:
385 friend class Node::UseEdges; 411 friend class Node::UseEdges;
386 412
387 iterator() : current_(NULL), next_(NULL) {} 413 iterator() : current_(nullptr), next_(nullptr) {}
388 explicit iterator(Node* node) 414 explicit iterator(Node* node)
389 : current_(node->first_use_), 415 : current_(node->first_use_),
390 next_(current_ == NULL ? NULL : current_->next) {} 416 next_(current_ ? current_->next : nullptr) {}
391
392 bool Equals(const iterator& other) const {
393 return other.current_ == current_;
394 }
395
396 Input* CurrentInput() const {
397 return current_->from->GetInputRecordPtr(current_->input_index);
398 }
399 417
400 Node::Use* current_; 418 Node::Use* current_;
401 Node::Use* next_; 419 Node::Use* next_;
402 }; 420 };
403 421
404 422
423 Node::UseEdges::iterator Node::UseEdges::begin() const {
424 return Node::UseEdges::iterator(this->node_);
425 }
426
427
428 Node::UseEdges::iterator Node::UseEdges::end() const {
429 return Node::UseEdges::iterator();
430 }
431
432
405 // 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
406 // the order in which they were added as inputs. 434 // the order in which they were added as inputs.
407 class Node::Uses::iterator { 435 class Node::Uses::const_iterator FINAL {
408 public: 436 public:
409 iterator(const Node::Uses::iterator& other) // NOLINT 437 typedef std::forward_iterator_tag iterator_category;
410 : current_(other.current_) {} 438 typedef int difference_type;
439 typedef Node* value_type;
440 typedef Node** pointer;
441 typedef Node*& reference;
411 442
412 Node* operator*() { return current_->from; } 443 const_iterator(const const_iterator& other) : current_(other.current_) {}
413 444
414 bool operator==(const iterator& other) { return other.current_ == current_; } 445 Node* operator*() const { return current_->from; }
415 bool operator!=(const iterator& other) { return other.current_ != current_; } 446 bool operator==(const const_iterator& other) const {
416 iterator& operator++() { 447 return other.current_ == current_;
417 DCHECK(current_ != NULL); 448 }
449 bool operator!=(const const_iterator& other) const {
450 return other.current_ != current_;
451 }
452 const_iterator& operator++() {
453 DCHECK_NOT_NULL(current_);
418 current_ = current_->next; 454 current_ = current_->next;
419 return *this; 455 return *this;
420 } 456 }
457 const_iterator operator++(int);
421 458
422 private: 459 private:
423 friend class Node::Uses; 460 friend class Node::Uses;
424 461
425 iterator() : current_(NULL) {} 462 const_iterator() : current_(nullptr) {}
426 explicit iterator(Node* node) : current_(node->first_use_) {} 463 explicit const_iterator(Node* node) : current_(node->first_use_) {}
427
428 Input* CurrentInput() const {
429 return current_->from->GetInputRecordPtr(current_->input_index);
430 }
431 464
432 Node::Use* current_; 465 Node::Use* current_;
433 }; 466 };
434 467
435 468
436 std::ostream& operator<<(std::ostream& os, const Node& n); 469 Node::Uses::const_iterator Node::Uses::begin() const {
437 470 return const_iterator(this->node_);
438 typedef ZoneDeque<Node*> NodeDeque;
439
440 typedef ZoneVector<Node*> NodeVector;
441 typedef NodeVector::iterator NodeVectorIter;
442 typedef NodeVector::const_iterator NodeVectorConstIter;
443 typedef NodeVector::reverse_iterator NodeVectorRIter;
444
445 typedef ZoneVector<NodeVector> NodeVectorVector;
446 typedef NodeVectorVector::iterator NodeVectorVectorIter;
447 typedef NodeVectorVector::reverse_iterator NodeVectorVectorRIter;
448
449 typedef Node::Uses::iterator UseIter;
450 typedef Node::Inputs::iterator InputIter;
451
452 // Helper to extract parameters from Operator1<*> nodes.
453 template <typename T>
454 static inline const T& OpParameter(const Node* node) {
455 return OpParameter<T>(node->op());
456 } 471 }
457 472
458 inline Node::InputEdges::iterator Node::InputEdges::begin() const {
459 return Node::InputEdges::iterator(this->node_, 0);
460 }
461 473
462 inline Node::InputEdges::iterator Node::InputEdges::end() const { 474 Node::Uses::const_iterator Node::Uses::end() const { return const_iterator(); }
463 return Node::InputEdges::iterator(this->node_, this->node_->InputCount());
464 }
465 475
466 inline Node::Inputs::iterator Node::Inputs::begin() const {
467 return Node::Inputs::iterator(this->node_, 0);
468 }
469 476
470 inline Node::Inputs::iterator Node::Inputs::end() const { 477 void Node::ReplaceInput(int index, Node* new_to) {
471 return Node::Inputs::iterator(this->node_, this->node_->InputCount()); 478 GetInputRecordPtr(index)->Update(new_to);
472 }
473
474 inline Node::UseEdges::iterator Node::UseEdges::begin() const {
475 return Node::UseEdges::iterator(this->node_);
476 }
477
478 inline Node::UseEdges::iterator Node::UseEdges::end() const {
479 return Node::UseEdges::iterator();
480 }
481
482 inline Node::Uses::iterator Node::Uses::begin() const {
483 return Node::Uses::iterator(this->node_);
484 }
485
486 inline Node::Uses::iterator Node::Uses::end() const {
487 return Node::Uses::iterator();
488 }
489
490 inline bool Node::InputEdges::empty() const { return begin() == end(); }
491 inline bool Node::Uses::empty() const { return begin() == end(); }
492 inline bool Node::UseEdges::empty() const { return begin() == end(); }
493 inline bool Node::Inputs::empty() const { return begin() == end(); }
494
495 inline void Node::ReplaceUses(Node* replace_to) {
496 for (Use* use = first_use_; use != NULL; use = use->next) {
497 use->from->GetInputRecordPtr(use->input_index)->to = replace_to;
498 }
499 if (replace_to->last_use_ == NULL) {
500 DCHECK_EQ(NULL, replace_to->first_use_);
501 replace_to->first_use_ = first_use_;
502 replace_to->last_use_ = last_use_;
503 } else if (first_use_ != NULL) {
504 DCHECK_NE(NULL, replace_to->first_use_);
505 replace_to->last_use_->next = first_use_;
506 first_use_->prev = replace_to->last_use_;
507 replace_to->last_use_ = last_use_;
508 }
509 first_use_ = NULL;
510 last_use_ = NULL;
511 }
512
513 template <class UnaryPredicate>
514 inline void Node::ReplaceUsesIf(UnaryPredicate pred, Node* replace_to) {
515 for (Use* use = first_use_; use != NULL;) {
516 Use* next = use->next;
517 if (pred(use->from)) {
518 RemoveUse(use);
519 replace_to->AppendUse(use);
520 use->from->GetInputRecordPtr(use->input_index)->to = replace_to;
521 }
522 use = next;
523 }
524 }
525
526 inline void Node::RemoveAllInputs() {
527 for (Edge edge : input_edges()) {
528 edge.UpdateTo(NULL);
529 }
530 }
531
532 inline void Node::TrimInputCount(int new_input_count) {
533 if (new_input_count == input_count()) return; // Nothing to do.
534
535 DCHECK(new_input_count < input_count());
536
537 // Update inline inputs.
538 for (int i = new_input_count; i < input_count(); i++) {
539 Node::Input* input = GetInputRecordPtr(i);
540 input->Update(NULL);
541 }
542 set_input_count(new_input_count);
543 }
544
545 inline void Node::ReplaceInput(int index, Node* new_to) {
546 Input* input = GetInputRecordPtr(index);
547 input->Update(new_to);
548 }
549
550 inline void Node::Input::Update(Node* new_to) {
551 Node* old_to = this->to;
552 if (new_to == old_to) return; // Nothing to do.
553 // Snip out the use from where it used to be
554 if (old_to != NULL) {
555 old_to->RemoveUse(use);
556 }
557 to = new_to;
558 // And put it into the new node's use list.
559 if (new_to != NULL) {
560 new_to->AppendUse(use);
561 } else {
562 use->next = NULL;
563 use->prev = NULL;
564 }
565 }
566
567 inline void Node::EnsureAppendableInputs(Zone* zone) {
568 if (!has_appendable_inputs()) {
569 void* deque_buffer = zone->New(sizeof(InputDeque));
570 InputDeque* deque = new (deque_buffer) InputDeque(zone);
571 for (int i = 0; i < input_count(); ++i) {
572 deque->push_back(inputs_.static_[i]);
573 }
574 inputs_.appendable_ = deque;
575 set_has_appendable_inputs(true);
576 }
577 }
578
579 inline void Node::AppendInput(Zone* zone, Node* to_append) {
580 Use* new_use = new (zone) Use;
581 Input new_input;
582 new_input.to = to_append;
583 new_input.use = new_use;
584 if (reserved_input_count() > 0) {
585 DCHECK(!has_appendable_inputs());
586 set_reserved_input_count(reserved_input_count() - 1);
587 inputs_.static_[input_count()] = new_input;
588 } else {
589 EnsureAppendableInputs(zone);
590 inputs_.appendable_->push_back(new_input);
591 }
592 new_use->input_index = input_count();
593 new_use->from = this;
594 to_append->AppendUse(new_use);
595 set_input_count(input_count() + 1);
596 }
597
598 inline void Node::InsertInput(Zone* zone, int index, Node* to_insert) {
599 DCHECK(index >= 0 && index < InputCount());
600 // TODO(turbofan): Optimize this implementation!
601 AppendInput(zone, InputAt(InputCount() - 1));
602 for (int i = InputCount() - 1; i > index; --i) {
603 ReplaceInput(i, InputAt(i - 1));
604 }
605 ReplaceInput(index, to_insert);
606 }
607
608 inline void Node::RemoveInput(int index) {
609 DCHECK(index >= 0 && index < InputCount());
610 // TODO(turbofan): Optimize this implementation!
611 for (; index < InputCount() - 1; ++index) {
612 ReplaceInput(index, InputAt(index + 1));
613 }
614 TrimInputCount(InputCount() - 1);
615 }
616
617 inline void Node::AppendUse(Use* use) {
618 use->next = NULL;
619 use->prev = last_use_;
620 if (last_use_ == NULL) {
621 first_use_ = use;
622 } else {
623 last_use_->next = use;
624 }
625 last_use_ = use;
626 }
627
628 inline void Node::RemoveUse(Use* use) {
629 if (last_use_ == use) {
630 last_use_ = use->prev;
631 }
632 if (use->prev != NULL) {
633 use->prev->next = use->next;
634 } else {
635 first_use_ = use->next;
636 }
637 if (use->next != NULL) {
638 use->next->prev = use->prev;
639 }
640 }
641
642 inline bool Node::OwnedBy(Node* owner) const {
643 return first_use_ != NULL && first_use_->from == owner &&
644 first_use_->next == NULL;
645 } 479 }
646 480
647 } // namespace compiler 481 } // namespace compiler
648 } // namespace internal 482 } // namespace internal
649 } // namespace v8 483 } // namespace v8
650 484
651 #endif // V8_COMPILER_NODE_H_ 485 #endif // V8_COMPILER_NODE_H_
OLDNEW
« no previous file with comments | « src/compiler/mips64/instruction-selector-mips64.cc ('k') | src/compiler/node.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698