| Index: src/compiler/node.h
|
| diff --git a/src/compiler/node.h b/src/compiler/node.h
|
| index 303ea1b44ebe7e5d9dabd7db6ca35a2d2a3e8fb7..3a5afd25dad800d070a901eecce8ca2591b0c7e8 100644
|
| --- a/src/compiler/node.h
|
| +++ b/src/compiler/node.h
|
| @@ -10,34 +10,19 @@
|
| #include <vector>
|
|
|
| #include "src/compiler/generic-algorithm.h"
|
| +#include "src/compiler/generic-node.h"
|
| #include "src/compiler/opcodes.h"
|
| #include "src/compiler/operator.h"
|
| #include "src/types.h"
|
| #include "src/zone.h"
|
| #include "src/zone-allocator.h"
|
| -#include "src/zone-containers.h"
|
|
|
| namespace v8 {
|
| namespace internal {
|
| namespace compiler {
|
|
|
| -// A Node is the basic primitive of an IR graph. In addition to the graph
|
| -// book-keeping Nodes only contain a mutable Operator that may change
|
| -// during compilation, e.g. during lowering passes. Other information that
|
| -// needs to be associated with Nodes during compilation must be stored
|
| -// out-of-line indexed by the Node's id.
|
| -class Node FINAL {
|
| +class NodeData {
|
| public:
|
| - Node(GenericGraphBase* graph, int input_count, int reserve_input_count);
|
| -
|
| - void Initialize(const Operator* op) { set_op(op); }
|
| -
|
| - bool IsDead() const { return InputCount() > 0 && InputAt(0) == NULL; }
|
| - void Kill();
|
| -
|
| - void CollectProjections(ZoneVector<Node*>* projections);
|
| - Node* FindProjection(size_t projection_index);
|
| -
|
| const Operator* op() const { return op_; }
|
| void set_op(const Operator* op) { op_ = op; }
|
|
|
| @@ -46,258 +31,38 @@ class Node FINAL {
|
| return static_cast<IrOpcode::Value>(op_->opcode());
|
| }
|
|
|
| - inline NodeId id() const { return id_; }
|
| -
|
| - int InputCount() const { return input_count_; }
|
| - Node* InputAt(int index) const {
|
| - return static_cast<Node*>(GetInputRecordPtr(index)->to);
|
| - }
|
| -
|
| - void ReplaceInput(int index, Node* new_input);
|
| - void AppendInput(Zone* zone, Node* new_input);
|
| - void InsertInput(Zone* zone, int index, Node* new_input);
|
| - void RemoveInput(int index);
|
| -
|
| - int UseCount() { return use_count_; }
|
| - Node* UseAt(int index) {
|
| - DCHECK(index < use_count_);
|
| - Use* current = first_use_;
|
| - while (index-- != 0) {
|
| - current = current->next;
|
| - }
|
| - return current->from;
|
| - }
|
| - void ReplaceUses(Node* replace_to);
|
| - template <class UnaryPredicate>
|
| - inline void ReplaceUsesIf(UnaryPredicate pred, Node* replace_to);
|
| - void RemoveAllInputs();
|
| -
|
| - void TrimInputCount(int input_count);
|
| -
|
| - class Inputs {
|
| - public:
|
| - class iterator;
|
| - iterator begin();
|
| - iterator end();
|
| -
|
| - explicit Inputs(Node* node) : node_(node) {}
|
| -
|
| - private:
|
| - Node* node_;
|
| - };
|
| -
|
| - Inputs inputs() { return Inputs(this); }
|
| -
|
| - class Uses {
|
| - public:
|
| - class iterator;
|
| - iterator begin();
|
| - iterator end();
|
| - bool empty(); // { return begin() == end(); }
|
| -
|
| - explicit Uses(Node* node) : node_(node) {}
|
| -
|
| - private:
|
| - Node* node_;
|
| - };
|
| -
|
| - Uses uses() { return Uses(this); }
|
| -
|
| - class Edge;
|
| -
|
| - bool OwnedBy(Node* owner) const;
|
| -
|
| - static Node* New(GenericGraphBase* graph, int input_count, Node** inputs,
|
| - bool has_extensible_inputs);
|
| -
|
| -
|
| - private:
|
| + protected:
|
| const Operator* op_;
|
| Bounds bounds_;
|
| + explicit NodeData(Zone* zone) {}
|
|
|
| friend class NodeProperties;
|
| Bounds bounds() { return bounds_; }
|
| void set_bounds(Bounds b) { bounds_ = b; }
|
| -
|
| - friend class GenericGraphBase;
|
| -
|
| - class Use : public ZoneObject {
|
| - public:
|
| - Node* from;
|
| - Use* next;
|
| - Use* prev;
|
| - int input_index;
|
| - };
|
| -
|
| - class Input {
|
| - public:
|
| - Node* to;
|
| - Use* use;
|
| -
|
| - void Update(Node* new_to);
|
| - };
|
| -
|
| - void EnsureAppendableInputs(Zone* zone);
|
| -
|
| - Input* GetInputRecordPtr(int index) const {
|
| - if (has_appendable_inputs_) {
|
| - return &((*inputs_.appendable_)[index]);
|
| - } else {
|
| - return inputs_.static_ + index;
|
| - }
|
| - }
|
| -
|
| - void AppendUse(Use* use);
|
| - void RemoveUse(Use* use);
|
| -
|
| - void* operator new(size_t, void* location) { return location; }
|
| -
|
| - void AssignUniqueID(GenericGraphBase* graph);
|
| -
|
| - typedef ZoneDeque<Input> InputDeque;
|
| -
|
| - static const int kReservedInputCountBits = 2;
|
| - static const int kMaxReservedInputs = (1 << kReservedInputCountBits) - 1;
|
| - static const int kDefaultReservedInputs = kMaxReservedInputs;
|
| -
|
| - NodeId id_;
|
| - int input_count_ : 29;
|
| - unsigned int reserve_input_count_ : kReservedInputCountBits;
|
| - bool has_appendable_inputs_ : 1;
|
| - union {
|
| - // When a node is initially allocated, it uses a static buffer to hold its
|
| - // inputs under the assumption that the number of outputs will not increase.
|
| - // When the first input is appended, the static buffer is converted into a
|
| - // deque to allow for space-efficient growing.
|
| - Input* static_;
|
| - InputDeque* appendable_;
|
| - } inputs_;
|
| - int use_count_;
|
| - Use* first_use_;
|
| - Use* last_use_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(Node);
|
| -};
|
| -
|
| -class Node::Edge {
|
| - public:
|
| - Node* from() const { return input_->use->from; }
|
| - Node* to() const { return input_->to; }
|
| - int index() const {
|
| - int index = input_->use->input_index;
|
| - DCHECK(index < input_->use->from->input_count_);
|
| - return index;
|
| - }
|
| -
|
| - private:
|
| - friend class Node::Uses::iterator;
|
| - friend class Node::Inputs::iterator;
|
| -
|
| - explicit Edge(Node::Input* input) : input_(input) {}
|
| -
|
| - Node::Input* input_;
|
| };
|
|
|
| -
|
| -// A forward iterator to visit the nodes which are depended upon by a node
|
| -// in the order of input.
|
| -class Node::Inputs::iterator {
|
| - public:
|
| - iterator(const Node::Inputs::iterator& other) // NOLINT
|
| - : node_(other.node_),
|
| - index_(other.index_) {}
|
| -
|
| - 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); }
|
| - iterator& operator++() {
|
| - DCHECK(node_ != NULL);
|
| - DCHECK(index_ < node_->input_count_);
|
| - ++index_;
|
| - return *this;
|
| - }
|
| - iterator& UpdateToAndIncrement(Node* new_to) {
|
| - Node::Input* input = GetInput();
|
| - input->Update(new_to);
|
| - index_++;
|
| - return *this;
|
| - }
|
| - int index() { return index_; }
|
| -
|
| - private:
|
| - friend class Node;
|
| -
|
| - explicit iterator(Node* node, int index) : node_(node), index_(index) {}
|
| -
|
| - Input* GetInput() const { return node_->GetInputRecordPtr(index_); }
|
| -
|
| - Node* node_;
|
| - int index_;
|
| -};
|
| -
|
| -// A forward iterator to visit the uses of a node. The uses are returned in
|
| -// the order in which they were added as inputs.
|
| -class Node::Uses::iterator {
|
| +// A Node is the basic primitive of an IR graph. In addition to the members
|
| +// inherited from Vector, Nodes only contain a mutable Operator that may change
|
| +// during compilation, e.g. during lowering passes. Other information that
|
| +// needs to be associated with Nodes during compilation must be stored
|
| +// out-of-line indexed by the Node's id.
|
| +class Node FINAL : public GenericNode<NodeData, Node> {
|
| public:
|
| - iterator(const Node::Uses::iterator& other) // NOLINT
|
| - : current_(other.current_),
|
| - index_(other.index_) {}
|
| -
|
| - 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;
|
| + Node(GenericGraphBase* graph, int input_count, int reserve_input_count)
|
| + : GenericNode<NodeData, Node>(graph, input_count, reserve_input_count) {}
|
|
|
| - iterator() : current_(NULL), index_(0) {}
|
| - explicit iterator(Node* node) : current_(node->first_use_), index_(0) {}
|
| + void Initialize(const Operator* op) { set_op(op); }
|
|
|
| - Input* CurrentInput() const {
|
| - return current_->from->GetInputRecordPtr(current_->input_index);
|
| - }
|
| + bool IsDead() const { return InputCount() > 0 && InputAt(0) == NULL; }
|
| + void Kill();
|
|
|
| - Node::Use* current_;
|
| - int index_;
|
| + void CollectProjections(ZoneVector<Node*>* projections);
|
| + Node* FindProjection(size_t projection_index);
|
| };
|
|
|
| -
|
| -template <class UnaryPredicate>
|
| -inline void Node::ReplaceUsesIf(UnaryPredicate pred, Node* replace_to) {
|
| - for (Use* use = first_use_; use != NULL;) {
|
| - Use* next = use->next;
|
| - if (pred(use->from)) {
|
| - RemoveUse(use);
|
| - replace_to->AppendUse(use);
|
| - use->from->GetInputRecordPtr(use->input_index)->to = replace_to;
|
| - }
|
| - use = next;
|
| - }
|
| -}
|
| -
|
| std::ostream& operator<<(std::ostream& os, const Node& n);
|
|
|
| -typedef GenericGraphVisit::NullNodeVisitor<Node> NullNodeVisitor;
|
| +typedef GenericGraphVisit::NullNodeVisitor<NodeData, Node> NullNodeVisitor;
|
|
|
| typedef std::set<Node*, std::less<Node*>, zone_allocator<Node*> > NodeSet;
|
| typedef NodeSet::iterator NodeSetIter;
|
|
|