Index: src/compiler/node.h |
diff --git a/src/compiler/node.h b/src/compiler/node.h |
index a3704961689b11ffac701c2e01d7eea9432266d5..6291ddf8466165b0a4699646d996d7b7b1f18769 100644 |
--- a/src/compiler/node.h |
+++ b/src/compiler/node.h |
@@ -23,6 +23,7 @@ namespace v8 { |
namespace internal { |
namespace compiler { |
+class Edge; |
class Graph; |
// Marks are used during traversal of the graph to distinguish states of nodes. |
@@ -89,11 +90,25 @@ class Node FINAL { |
inline void TrimInputCount(int input_count); |
+ class InputEdges { |
+ public: |
+ class iterator; |
+ iterator begin() const; |
+ iterator end() const; |
+ bool empty() const; |
+ |
+ explicit InputEdges(Node* node) : node_(node) {} |
+ |
+ private: |
+ Node* node_; |
+ }; |
+ |
class Inputs { |
public: |
class iterator; |
- iterator begin(); |
- iterator end(); |
+ iterator begin() const; |
+ iterator end() const; |
+ bool empty() const; |
explicit Inputs(Node* node) : node_(node) {} |
@@ -102,13 +117,27 @@ class Node FINAL { |
}; |
Inputs inputs() { return Inputs(this); } |
+ InputEdges input_edges() { return InputEdges(this); } |
+ |
+ class UseEdges { |
+ public: |
+ class iterator; |
+ iterator begin() const; |
+ iterator end() const; |
+ bool empty() const; |
+ |
+ explicit UseEdges(Node* node) : node_(node) {} |
+ |
+ private: |
+ Node* node_; |
+ }; |
class Uses { |
public: |
class iterator; |
- iterator begin(); |
- iterator end(); |
- bool empty(); |
+ iterator begin() const; |
+ iterator end() const; |
+ bool empty() const; |
explicit Uses(Node* node) : node_(node) {} |
@@ -117,8 +146,7 @@ class Node FINAL { |
}; |
Uses uses() { return Uses(this); } |
- |
- class Edge; |
+ UseEdges use_edges() { return UseEdges(this); } |
bool OwnedBy(Node* owner) const; |
@@ -127,6 +155,7 @@ class Node FINAL { |
protected: |
friend class Graph; |
+ friend class Edge; |
class Use : public ZoneObject { |
public: |
@@ -205,8 +234,8 @@ class Node FINAL { |
// An encapsulation for information associated with a single use of node as a |
// input from another node, allowing access to both the defining node and |
-// the ndoe having the input. |
-class Node::Edge { |
+// the node having the input. |
+class Edge { |
public: |
Node* from() const { return input_->use->from; } |
Node* to() const { return input_->to; } |
@@ -216,9 +245,16 @@ class Node::Edge { |
return index; |
} |
+ bool operator==(const Edge& other) { return input_ == other.input_; } |
+ bool operator!=(const Edge& other) { return !(*this == other); } |
+ |
+ void UpdateTo(Node* new_to) { input_->Update(new_to); } |
+ |
private: |
friend class Node::Uses::iterator; |
friend class Node::Inputs::iterator; |
+ friend class Node::UseEdges::iterator; |
+ friend class Node::InputEdges::iterator; |
explicit Edge(Node::Input* input) : input_(input) {} |
@@ -226,43 +262,134 @@ class Node::Edge { |
}; |
-// A forward iterator to visit the nodes which are depended upon by a node |
-// in the order of input. |
+// A forward iterator to visit the edges for the input dependencies of a node.. |
+class Node::InputEdges::iterator { |
+ public: |
+ typedef std::forward_iterator_tag iterator_category; |
+ typedef int difference_type; |
+ typedef Edge value_type; |
+ typedef Edge* pointer; |
+ typedef Edge& reference; |
+ iterator(const Node::InputEdges::iterator& other) // NOLINT |
+ : input_(other.input_) {} |
+ iterator() : input_(NULL) {} |
+ |
+ Edge operator*() const { return Edge(input_); } |
+ bool operator==(const iterator& other) const { return Equals(other); } |
+ bool operator!=(const iterator& other) const { return !Equals(other); } |
+ iterator& operator++() { |
+ DCHECK(input_ != NULL); |
+ Edge edge(input_); |
+ Node* from = edge.from(); |
+ SetInput(from, input_->use->input_index + 1); |
+ return *this; |
+ } |
+ iterator operator++(int) { |
+ iterator result(*this); |
+ ++(*this); |
+ return result; |
+ } |
+ |
+ private: |
+ friend class Node; |
+ |
+ explicit iterator(Node* from, int index = 0) : input_(NULL) { |
+ SetInput(from, index); |
+ } |
+ |
+ bool Equals(const iterator& other) const { return other.input_ == input_; } |
+ void SetInput(Node* from, int index) { |
+ DCHECK(index >= 0 && index <= from->InputCount()); |
+ if (index < from->InputCount()) { |
+ input_ = from->GetInputRecordPtr(index); |
+ } else { |
+ input_ = NULL; |
+ } |
+ } |
+ |
+ Input* input_; |
+}; |
+ |
+ |
+// A forward iterator to visit the inputs of a node. |
class Node::Inputs::iterator { |
public: |
+ typedef std::forward_iterator_tag iterator_category; |
+ typedef int difference_type; |
+ typedef Node* value_type; |
+ typedef Node** pointer; |
+ typedef Node*& reference; |
+ |
iterator(const Node::Inputs::iterator& other) // NOLINT |
- : node_(other.node_), |
- index_(other.index_) {} |
+ : iter_(other.iter_) {} |
- Node* operator*() { return GetInput()->to; } |
- Node::Edge edge() { return Node::Edge(GetInput()); } |
- bool operator==(const iterator& other) const { |
- return other.index_ == index_ && other.node_ == node_; |
- } |
- bool operator!=(const iterator& other) const { return !(other == *this); } |
+ Node* operator*() const { return (*iter_).to(); } |
+ bool operator==(const iterator& other) const { return Equals(other); } |
+ bool operator!=(const iterator& other) const { return !Equals(other); } |
iterator& operator++() { |
- DCHECK(node_ != NULL); |
- DCHECK(index_ < node_->input_count_); |
- ++index_; |
+ ++iter_; |
return *this; |
} |
- iterator& UpdateToAndIncrement(Node* new_to) { |
- Node::Input* input = GetInput(); |
- input->Update(new_to); |
- index_++; |
+ iterator operator++(int) { |
+ iterator result(*this); |
+ ++(*this); |
+ return result; |
+ } |
+ |
+ |
+ private: |
+ friend class Node::Inputs; |
+ |
+ explicit iterator(Node* node, int index) : iter_(node, index) {} |
+ |
+ bool Equals(const iterator& other) const { return other.iter_ == iter_; } |
+ |
+ Node::InputEdges::iterator iter_; |
+}; |
+ |
+// A forward iterator to visit the uses edges of a node. The edges are returned |
+// in |
+// the order in which they were added as inputs. |
+class Node::UseEdges::iterator { |
+ public: |
+ iterator(const Node::UseEdges::iterator& other) // NOLINT |
+ : current_(other.current_), |
+ next_(other.next_) {} |
+ |
+ Edge operator*() const { return Edge(CurrentInput()); } |
+ |
+ bool operator==(const iterator& other) { return Equals(other); } |
+ bool operator!=(const iterator& other) { return !Equals(other); } |
+ iterator& operator++() { |
+ DCHECK(current_ != NULL); |
+ current_ = next_; |
+ next_ = (current_ == NULL) ? NULL : current_->next; |
return *this; |
} |
- int index() { return index_; } |
+ iterator operator++(int) { |
+ iterator result(*this); |
+ ++(*this); |
+ return result; |
+ } |
private: |
- friend class Node; |
+ friend class Node::UseEdges; |
+ |
+ iterator() : current_(NULL), next_(NULL) {} |
+ explicit iterator(Node* node) |
+ : current_(node->first_use_), |
+ next_(current_ == NULL ? NULL : current_->next) {} |
- explicit iterator(Node* node, int index) : node_(node), index_(index) {} |
+ bool Equals(const iterator& other) const { |
+ return other.current_ == current_; |
+ } |
- Input* GetInput() const { return node_->GetInputRecordPtr(index_); } |
+ Input* CurrentInput() const { |
+ return current_->from->GetInputRecordPtr(current_->input_index); |
+ } |
- Node* node_; |
- int index_; |
+ Node::Use* current_; |
+ Node::Use* next_; |
}; |
@@ -271,42 +398,29 @@ class Node::Inputs::iterator { |
class Node::Uses::iterator { |
public: |
iterator(const Node::Uses::iterator& other) // NOLINT |
- : current_(other.current_), |
- index_(other.index_) {} |
+ : current_(other.current_) {} |
Node* operator*() { return current_->from; } |
- Node::Edge edge() { return Node::Edge(CurrentInput()); } |
bool operator==(const iterator& other) { return other.current_ == current_; } |
bool operator!=(const iterator& other) { return other.current_ != current_; } |
iterator& operator++() { |
DCHECK(current_ != NULL); |
- index_++; |
- current_ = current_->next; |
- return *this; |
- } |
- iterator& UpdateToAndIncrement(Node* new_to) { |
- DCHECK(current_ != NULL); |
- index_++; |
- Node::Input* input = CurrentInput(); |
current_ = current_->next; |
- input->Update(new_to); |
return *this; |
} |
- int index() const { return index_; } |
private: |
friend class Node::Uses; |
- iterator() : current_(NULL), index_(0) {} |
- explicit iterator(Node* node) : current_(node->first_use_), index_(0) {} |
+ iterator() : current_(NULL) {} |
+ explicit iterator(Node* node) : current_(node->first_use_) {} |
Input* CurrentInput() const { |
return current_->from->GetInputRecordPtr(current_->input_index); |
} |
Node::Use* current_; |
- int index_; |
}; |
@@ -338,21 +452,42 @@ static inline const T& OpParameter(const Node* node) { |
return OpParameter<T>(node->op()); |
} |
-inline Node::Inputs::iterator Node::Inputs::begin() { |
+inline Node::InputEdges::iterator Node::InputEdges::begin() const { |
+ return Node::InputEdges::iterator(this->node_, 0); |
+} |
+ |
+inline Node::InputEdges::iterator Node::InputEdges::end() const { |
+ return Node::InputEdges::iterator(this->node_, this->node_->InputCount()); |
+} |
+ |
+inline Node::Inputs::iterator Node::Inputs::begin() const { |
return Node::Inputs::iterator(this->node_, 0); |
} |
-inline Node::Inputs::iterator Node::Inputs::end() { |
+inline Node::Inputs::iterator Node::Inputs::end() const { |
return Node::Inputs::iterator(this->node_, this->node_->InputCount()); |
} |
-inline Node::Uses::iterator Node::Uses::begin() { |
+inline Node::UseEdges::iterator Node::UseEdges::begin() const { |
+ return Node::UseEdges::iterator(this->node_); |
+} |
+ |
+inline Node::UseEdges::iterator Node::UseEdges::end() const { |
+ return Node::UseEdges::iterator(); |
+} |
+ |
+inline Node::Uses::iterator Node::Uses::begin() const { |
return Node::Uses::iterator(this->node_); |
} |
-inline Node::Uses::iterator Node::Uses::end() { return Node::Uses::iterator(); } |
+inline Node::Uses::iterator Node::Uses::end() const { |
+ return Node::Uses::iterator(); |
+} |
-inline bool Node::Uses::empty() { return begin() == end(); } |
+inline bool Node::InputEdges::empty() const { return begin() == end(); } |
+inline bool Node::Uses::empty() const { return begin() == end(); } |
+inline bool Node::UseEdges::empty() const { return begin() == end(); } |
+inline bool Node::Inputs::empty() const { return begin() == end(); } |
inline void Node::ReplaceUses(Node* replace_to) { |
for (Use* use = first_use_; use != NULL; use = use->next) { |
@@ -388,9 +523,8 @@ inline void Node::ReplaceUsesIf(UnaryPredicate pred, Node* replace_to) { |
} |
inline void Node::RemoveAllInputs() { |
- for (Inputs::iterator iter(inputs().begin()); iter != inputs().end(); |
- ++iter) { |
- iter.GetInput()->Update(NULL); |
+ for (Edge edge : input_edges()) { |
+ edge.UpdateTo(NULL); |
} |
} |