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

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

Issue 765983002: Clean up node iteration (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Tweaks Created 6 years 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/js-inlining.cc ('k') | src/compiler/node-properties.h » ('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> 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
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
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
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
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
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_
OLDNEW
« no previous file with comments | « src/compiler/js-inlining.cc ('k') | src/compiler/node-properties.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698