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

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

Issue 765983002: Clean up node iteration (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix comment 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
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_GENERIC_NODE_H_ 5 #ifndef V8_COMPILER_GENERIC_NODE_H_
6 #define V8_COMPILER_GENERIC_NODE_H_ 6 #define V8_COMPILER_GENERIC_NODE_H_
7 7
8 #include "src/v8.h" 8 #include "src/v8.h"
9 9
10 #include "src/zone-containers.h" 10 #include "src/zone-containers.h"
11 11
12 namespace v8 { 12 namespace v8 {
13 namespace internal { 13 namespace internal {
14 namespace compiler { 14 namespace compiler {
15 15
16 class GenericGraphBase; 16 class GenericGraphBase;
17 template <class N>
18 class GenericEdge;
17 19
18 typedef int NodeId; 20 typedef int NodeId;
19 21
20 // A GenericNode<> is the basic primitive of graphs. GenericNode's are 22 // A GenericNode<> is the basic primitive of graphs. GenericNode's are
21 // chained together by input/use chains but by default otherwise contain only an 23 // chained together by input/use chains but by default otherwise contain only an
22 // identifying number which specific applications of graphs and nodes can use 24 // identifying number which specific applications of graphs and nodes can use
23 // to index auxiliary out-of-line data, especially transient data. 25 // to index auxiliary out-of-line data, especially transient data.
24 // Specializations of the templatized GenericNode<> class must provide a base 26 // Specializations of the templatized GenericNode<> class must provide a base
25 // class B that contains all of the members to be made available in each 27 // class B that contains all of the members to be made available in each
26 // specialized Node instance. GenericNode uses a mixin template pattern to 28 // specialized Node instance. GenericNode uses a mixin template pattern to
(...skipping 25 matching lines...) Expand all
52 } 54 }
53 return static_cast<S*>(current->from); 55 return static_cast<S*>(current->from);
54 } 56 }
55 inline void ReplaceUses(GenericNode* replace_to); 57 inline void ReplaceUses(GenericNode* replace_to);
56 template <class UnaryPredicate> 58 template <class UnaryPredicate>
57 inline void ReplaceUsesIf(UnaryPredicate pred, GenericNode* replace_to); 59 inline void ReplaceUsesIf(UnaryPredicate pred, GenericNode* replace_to);
58 inline void RemoveAllInputs(); 60 inline void RemoveAllInputs();
59 61
60 inline void TrimInputCount(int input_count); 62 inline void TrimInputCount(int input_count);
61 63
64 class InputEdges {
65 public:
66 class iterator;
67 iterator begin();
68 iterator end();
69 bool empty() { return begin() == end(); }
70
71 explicit InputEdges(GenericNode* node) : node_(node) {}
72
73 private:
74 GenericNode* node_;
75 };
76
62 class Inputs { 77 class Inputs {
63 public: 78 public:
64 class iterator; 79 class iterator;
65 iterator begin(); 80 iterator begin();
66 iterator end(); 81 iterator end();
82 bool empty() { return begin() == end(); }
67 83
68 explicit Inputs(GenericNode* node) : node_(node) {} 84 explicit Inputs(GenericNode* node) : node_(node) {}
69 85
70 private: 86 private:
71 GenericNode* node_; 87 GenericNode* node_;
72 }; 88 };
73 89
90 InputEdges input_edges() { return InputEdges(this); }
74 Inputs inputs() { return Inputs(this); } 91 Inputs inputs() { return Inputs(this); }
75 92
93 class UseEdges {
94 public:
95 class iterator;
96 iterator begin();
97 iterator end();
98 bool empty() { return begin() == end(); }
99
100 explicit UseEdges(GenericNode* node) : node_(node) {}
101
102 private:
103 GenericNode* node_;
104 };
105
76 class Uses { 106 class Uses {
77 public: 107 public:
78 class iterator; 108 class iterator;
79 iterator begin(); 109 iterator begin();
80 iterator end(); 110 iterator end();
81 bool empty() { return begin() == end(); } 111 bool empty() { return begin() == end(); }
82 112
83 explicit Uses(GenericNode* node) : node_(node) {} 113 explicit Uses(GenericNode* node) : node_(node) {}
84 114
85 private: 115 private:
86 GenericNode* node_; 116 GenericNode* node_;
87 }; 117 };
88 118
89 Uses uses() { return Uses(this); } 119 Uses uses() { return Uses(this); }
90 120 UseEdges use_edges() { return UseEdges(this); }
91 class Edge;
92 121
93 bool OwnedBy(GenericNode* owner) const; 122 bool OwnedBy(GenericNode* owner) const;
94 123
95 static S* New(GenericGraphBase* graph, int input_count, S** inputs, 124 static S* New(GenericGraphBase* graph, int input_count, S** inputs,
96 bool has_extensible_inputs); 125 bool has_extensible_inputs);
97 126
98 protected: 127 protected:
99 friend class GenericGraphBase; 128 friend class GenericGraphBase;
129 friend class GenericEdge<S>;
100 130
101 class Use : public ZoneObject { 131 class Use : public ZoneObject {
102 public: 132 public:
103 GenericNode* from; 133 GenericNode* from;
104 Use* next; 134 Use* next;
105 Use* prev; 135 Use* prev;
106 int input_index; 136 int input_index;
107 }; 137 };
108 138
109 class Input { 139 class Input {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
155 } inputs_; 185 } inputs_;
156 int use_count_; 186 int use_count_;
157 Use* first_use_; 187 Use* first_use_;
158 Use* last_use_; 188 Use* last_use_;
159 189
160 DISALLOW_COPY_AND_ASSIGN(GenericNode); 190 DISALLOW_COPY_AND_ASSIGN(GenericNode);
161 }; 191 };
162 192
163 // An encapsulation for information associated with a single use of node as a 193 // An encapsulation for information associated with a single use of node as a
164 // input from another node, allowing access to both the defining node and 194 // input from another node, allowing access to both the defining node and
165 // the ndoe having the input. 195 // the node having the input.
166 template <class B, class S> 196 template <class N>
167 class GenericNode<B, S>::Edge { 197 class GenericEdge {
168 public: 198 public:
169 S* from() const { return static_cast<S*>(input_->use->from); } 199 GenericEdge(const GenericEdge& other) : input_(other.input_) {}
170 S* to() const { return static_cast<S*>(input_->to); } 200 GenericEdge() : input_(NULL) {}
201
202 N* from() const { return static_cast<N*>(input_->use->from); }
203 N* to() const { return static_cast<N*>(input_->to); }
171 int index() const { 204 int index() const {
172 int index = input_->use->input_index; 205 int index = input_->use->input_index;
173 DCHECK(index < input_->use->from->input_count_); 206 DCHECK(index < input_->use->from->input_count_);
174 return index; 207 return index;
175 } 208 }
176 209 bool operator==(const GenericEdge& other) { return input_ == other.input_; }
177 private: 210 bool operator!=(const GenericEdge& other) { return !(*this == other); }
178 friend class GenericNode<B, S>::Uses::iterator; 211
179 friend class GenericNode<B, S>::Inputs::iterator; 212 explicit GenericEdge(typename N::Input* input) : input_(input) {}
180 213
181 explicit Edge(typename GenericNode<B, S>::Input* input) : input_(input) {} 214 void UpdateTo(N* new_to) { input_->Update(new_to); }
182 215
183 typename GenericNode<B, S>::Input* input_; 216 private:
184 }; 217 typename N::Input* input_;
218 };
219
185 220
186 // A forward iterator to visit the nodes which are depended upon by a node 221 // A forward iterator to visit the nodes which are depended upon by a node
187 // in the order of input. 222 // in the order of input.
188 template <class B, class S> 223 template <class B, class S>
224 class GenericNode<B, S>::InputEdges::iterator {
225 public:
226 typedef std::forward_iterator_tag iterator_category;
227 typedef int difference_type;
228 typedef GenericEdge<S> value_type;
229 typedef GenericEdge<S>* pointer;
230 typedef GenericEdge<S>& reference;
231 iterator(
232 const typename GenericNode<B, S>::InputEdges::iterator& other) // NOLINT
233 : input_(other.input_) {}
234 iterator() : input_(NULL) {}
235
236 GenericEdge<S> operator*() const { return GenericEdge<S>(input_); }
237 bool operator==(const iterator& other) const { return Equals(other); }
238 bool operator!=(const iterator& other) const { return !Equals(other); }
239 iterator& operator++() {
240 DCHECK(input_ != NULL);
241 GenericEdge<S> edge(input_);
242 GenericNode<B, S>* from = edge.from();
243 SetInput(from, input_->use->input_index + 1);
244 return *this;
245 }
246 iterator& operator++(int) {
247 iterator result(*this);
248 ++(*this);
249 return result;
250 }
251
252 private:
253 friend class GenericNode;
254
255 iterator(GenericNode* from, int index = 0) : input_(NULL) {
256 SetInput(from, index);
257 }
258
259 bool Equals(const iterator& other) const { return other.input_ == input_; }
260 void SetInput(GenericNode* from, int index) {
261 DCHECK(index >= 0 && index <= from->InputCount());
262 if (index < from->InputCount()) {
263 input_ = from->GetInputRecordPtr(index);
264 } else {
265 input_ = NULL;
266 }
267 }
268
269 Input* input_;
270 };
271
272
273 template <class B, class S>
189 class GenericNode<B, S>::Inputs::iterator { 274 class GenericNode<B, S>::Inputs::iterator {
190 public: 275 public:
276 typedef std::forward_iterator_tag iterator_category;
277 typedef int difference_type;
278 typedef S value_type;
279 typedef S* pointer;
280 typedef S& reference;
191 iterator(const typename GenericNode<B, S>::Inputs::iterator& other) // NOLINT 281 iterator(const typename GenericNode<B, S>::Inputs::iterator& other) // NOLINT
192 : node_(other.node_), 282 : iter_(other.iter_) {}
193 index_(other.index_) {} 283 iterator() {}
194 284
195 S* operator*() { return static_cast<S*>(GetInput()->to); } 285 S* operator*() const { return (*iter_).to(); }
196 typename GenericNode<B, S>::Edge edge() { 286 bool operator==(const iterator& other) const { return Equals(other); }
197 return typename GenericNode::Edge(GetInput()); 287 bool operator!=(const iterator& other) const { return !Equals(other); }
198 } 288 iterator& operator++() {
199 bool operator==(const iterator& other) const { 289 ++iter_;
200 return other.index_ == index_ && other.node_ == node_; 290 return *this;
201 } 291 }
202 bool operator!=(const iterator& other) const { return !(other == *this); } 292 iterator& operator++(int) {
203 iterator& operator++() { 293 iterator result(*this);
204 DCHECK(node_ != NULL); 294 ++(*this);
205 DCHECK(index_ < node_->input_count_); 295 return result;
206 ++index_; 296 }
207 return *this; 297
208 } 298 private:
209 iterator& UpdateToAndIncrement(GenericNode<B, S>* new_to) { 299 friend class GenericNode<B, S>::Inputs;
210 typename GenericNode<B, S>::Input* input = GetInput(); 300
211 input->Update(new_to); 301 iterator(GenericNode* from, int index = 0) : iter_(from, index) {}
212 index_++; 302
213 return *this; 303 bool Equals(const iterator& other) const { return other.iter_ == iter_; }
214 } 304
215 int index() { return index_; } 305 typename GenericNode<B, S>::InputEdges::iterator iter_;
216 306 };
217 private: 307
218 friend class GenericNode;
219
220 explicit iterator(GenericNode* node, int index)
221 : node_(node), index_(index) {}
222
223 Input* GetInput() const { return node_->GetInputRecordPtr(index_); }
224
225 GenericNode* node_;
226 int index_;
227 };
228 308
229 // A forward iterator to visit the uses of a node. The uses are returned in 309 // A forward iterator to visit the uses of a node. The uses are returned in
230 // the order in which they were added as inputs. 310 // the order in which they were added as inputs.
231 template <class B, class S> 311 template <class B, class S>
312 class GenericNode<B, S>::UseEdges::iterator {
313 public:
314 iterator(
315 const typename GenericNode<B, S>::UseEdges::iterator& other) // NOLINT
316 : current_(other.current_),
317 next_(other.next_),
318 index_(other.index_) {}
319
320 GenericEdge<S> operator*() const { return GenericEdge<S>(CurrentInput()); }
321
322 bool operator==(const iterator& other) { return Equals(other); }
323 bool operator!=(const iterator& other) { return !Equals(other); }
324 iterator& operator++() {
325 DCHECK(current_ != NULL);
326 index_++;
327 current_ = next_;
328 next_ = (current_ == NULL) ? NULL : current_->next;
329 return *this;
330 }
331 iterator& operator++(int) {
332 iterator result(*this);
333 ++(*this);
334 return result;
335 }
336
337 private:
338 friend class GenericNode<B, S>::UseEdges;
339
340 iterator() : current_(NULL), next_(NULL), index_(0) {}
341 explicit iterator(GenericNode<B, S>* node)
342 : current_(node->first_use_),
343 next_(current_ == NULL ? NULL : current_->next),
344 index_(0) {}
345
346 bool Equals(const iterator& other) const {
347 return other.current_ == current_;
348 }
349
350 Input* CurrentInput() const {
351 return current_->from->GetInputRecordPtr(current_->input_index);
352 }
353
354 typename GenericNode<B, S>::Use* current_;
355 typename GenericNode<B, S>::Use* next_;
356 int index_;
357 };
358
359
360 // A forward iterator to visit the uses edges of a node. The edges are returned
361 // in the order in which they were added as inputs.
362 template <class B, class S>
232 class GenericNode<B, S>::Uses::iterator { 363 class GenericNode<B, S>::Uses::iterator {
233 public: 364 public:
234 iterator(const typename GenericNode<B, S>::Uses::iterator& other) // NOLINT 365 iterator(const typename GenericNode<B, S>::Uses::iterator& other) // NOLINT
235 : current_(other.current_), 366 : current_(other.current_) {}
236 index_(other.index_) {}
237 367
238 S* operator*() { return static_cast<S*>(current_->from); } 368 S* operator*() { return static_cast<S*>(current_->from); }
239 typename GenericNode<B, S>::Edge edge() {
240 return typename GenericNode::Edge(CurrentInput());
241 }
242 369
243 bool operator==(const iterator& other) { return other.current_ == current_; } 370 bool operator==(const iterator& other) { return other.current_ == current_; }
244 bool operator!=(const iterator& other) { return other.current_ != current_; } 371 bool operator!=(const iterator& other) { return other.current_ != current_; }
245 iterator& operator++() { 372 iterator& operator++() {
246 DCHECK(current_ != NULL); 373 DCHECK(current_ != NULL);
247 index_++;
248 current_ = current_->next; 374 current_ = current_->next;
249 return *this; 375 return *this;
250 } 376 }
251 iterator& UpdateToAndIncrement(GenericNode<B, S>* new_to) {
252 DCHECK(current_ != NULL);
253 index_++;
254 typename GenericNode<B, S>::Input* input = CurrentInput();
255 current_ = current_->next;
256 input->Update(new_to);
257 return *this;
258 }
259 int index() const { return index_; }
260 377
261 private: 378 private:
262 friend class GenericNode<B, S>::Uses; 379 friend class GenericNode<B, S>::Uses;
263 380
264 iterator() : current_(NULL), index_(0) {} 381 iterator() : current_(NULL) {}
265 explicit iterator(GenericNode<B, S>* node) 382 explicit iterator(GenericNode<B, S>* node) : current_(node->first_use_) {}
266 : current_(node->first_use_), index_(0) {}
267 383
268 Input* CurrentInput() const { 384 Input* CurrentInput() const {
269 return current_->from->GetInputRecordPtr(current_->input_index); 385 return current_->from->GetInputRecordPtr(current_->input_index);
270 } 386 }
271 387
272 typename GenericNode<B, S>::Use* current_; 388 typename GenericNode<B, S>::Use* current_;
273 int index_;
274 }; 389 };
275 } 390 }
276 } 391 }
277 } // namespace v8::internal::compiler 392 } // namespace v8::internal::compiler
278 393
279 #endif // V8_COMPILER_GENERIC_NODE_H_ 394 #endif // V8_COMPILER_GENERIC_NODE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698