Commit e564b3fe authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Initial work on cleaning up the Node class.

- Remove use_count_, only used for debug builds and tests.
- Use BitField instead of the unreliable C++ bit fields.
- Improve memory layout.

R=mstarzinger@chromium.org

Review URL: https://codereview.chromium.org/780503002

Cr-Commit-Position: refs/heads/master@{#25632}
parent 708610e9
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
// found in the LICENSE file. // found in the LICENSE file.
#include "src/compiler/node.h" #include "src/compiler/node.h"
#include "src/compiler/graph.h" #include "src/compiler/graph.h"
#include "src/zone.h" #include "src/zone.h"
...@@ -10,16 +11,14 @@ namespace v8 { ...@@ -10,16 +11,14 @@ namespace v8 {
namespace internal { namespace internal {
namespace compiler { namespace compiler {
Node::Node(Graph* graph, int input_count, int reserve_input_count) Node::Node(NodeId id, int input_count, int reserved_input_count)
: input_count_(input_count), : id_(id),
reserve_input_count_(reserve_input_count), bit_field_(InputCountField::encode(input_count) |
has_appendable_inputs_(false), ReservedInputCountField::encode(reserved_input_count) |
use_count_(0), HasAppendableInputsField::encode(false)),
first_use_(NULL), first_use_(nullptr),
last_use_(NULL) { last_use_(nullptr) {
DCHECK(reserve_input_count <= kMaxReservedInputs);
inputs_.static_ = reinterpret_cast<Input*>(this + 1); inputs_.static_ = reinterpret_cast<Input*>(this + 1);
id_ = graph->NextNodeID();
} }
...@@ -32,7 +31,8 @@ Node* Node::New(Graph* graph, int input_count, Node** inputs, ...@@ -32,7 +31,8 @@ Node* Node::New(Graph* graph, int input_count, Node** inputs,
int size = static_cast<int>(node_size + inputs_size + uses_size); int size = static_cast<int>(node_size + inputs_size + uses_size);
Zone* zone = graph->zone(); Zone* zone = graph->zone();
void* buffer = zone->New(size); void* buffer = zone->New(size);
Node* result = new (buffer) Node(graph, input_count, reserve_input_count); Node* result =
new (buffer) Node(graph->NextNodeID(), input_count, reserve_input_count);
Input* input = Input* input =
reinterpret_cast<Input*>(reinterpret_cast<char*>(buffer) + node_size); reinterpret_cast<Input*>(reinterpret_cast<char*>(buffer) + node_size);
Use* use = Use* use =
...@@ -84,6 +84,26 @@ Node* Node::FindProjection(size_t projection_index) { ...@@ -84,6 +84,26 @@ Node* Node::FindProjection(size_t projection_index) {
} }
int Node::UseCount() const {
int use_count = 0;
for (const Use* use = first_use_; use; use = use->next) {
++use_count;
}
return use_count;
}
Node* Node::UseAt(int index) const {
DCHECK_LE(0, index);
DCHECK_LT(index, UseCount());
Use* current = first_use_;
while (index-- != 0) {
current = current->next;
}
return current->from;
}
std::ostream& operator<<(std::ostream& os, const Node& n) { std::ostream& operator<<(std::ostream& os, const Node& n) {
os << n.id() << ": " << *n.op(); os << n.id() << ": " << *n.op();
if (n.InputCount() > 0) { if (n.InputCount() > 0) {
......
...@@ -22,9 +22,11 @@ namespace v8 { ...@@ -22,9 +22,11 @@ namespace v8 {
namespace internal { namespace internal {
namespace compiler { namespace compiler {
// Forward declarations.
class Edge; class Edge;
class Graph; class Graph;
// Marks are used during traversal of the graph to distinguish states of nodes. // Marks are used during traversal of the graph to distinguish states of nodes.
// Each node has a mark which is a monotonically increasing integer, and a // Each node has a mark which is a monotonically increasing integer, and a
// {NodeMarker} has a range of values that indicate states of a node. // {NodeMarker} has a range of values that indicate states of a node.
...@@ -66,22 +68,15 @@ class Node FINAL { ...@@ -66,22 +68,15 @@ class Node FINAL {
NodeId id() const { return id_; } NodeId id() const { return id_; }
int InputCount() const { return input_count_; } int InputCount() const { return input_count(); }
Node* InputAt(int index) const { return GetInputRecordPtr(index)->to; } Node* InputAt(int index) const { return GetInputRecordPtr(index)->to; }
inline void ReplaceInput(int index, Node* new_input); inline void ReplaceInput(int index, Node* new_input);
inline void AppendInput(Zone* zone, Node* new_input); inline void AppendInput(Zone* zone, Node* new_input);
inline void InsertInput(Zone* zone, int index, Node* new_input); inline void InsertInput(Zone* zone, int index, Node* new_input);
inline void RemoveInput(int index); inline void RemoveInput(int index);
int UseCount() { return use_count_; } int UseCount() const;
Node* UseAt(int index) { Node* UseAt(int index) const;
DCHECK(index < use_count_);
Use* current = first_use_;
while (index-- != 0) {
current = current->next;
}
return current->from;
}
inline void ReplaceUses(Node* replace_to); inline void ReplaceUses(Node* replace_to);
template <class UnaryPredicate> template <class UnaryPredicate>
inline void ReplaceUsesIf(UnaryPredicate pred, Node* replace_to); inline void ReplaceUsesIf(UnaryPredicate pred, Node* replace_to);
...@@ -175,10 +170,10 @@ class Node FINAL { ...@@ -175,10 +170,10 @@ class Node FINAL {
void EnsureAppendableInputs(Zone* zone); void EnsureAppendableInputs(Zone* zone);
Input* GetInputRecordPtr(int index) const { Input* GetInputRecordPtr(int index) const {
if (has_appendable_inputs_) { if (has_appendable_inputs()) {
return &((*inputs_.appendable_)[index]); return &((*inputs_.appendable_)[index]);
} else { } else {
return inputs_.static_ + index; return &inputs_.static_[index];
} }
} }
...@@ -188,7 +183,7 @@ class Node FINAL { ...@@ -188,7 +183,7 @@ class Node FINAL {
void* operator new(size_t, void* location) { return location; } void* operator new(size_t, void* location) { return location; }
private: private:
Node(Graph* graph, int input_count, int reserve_input_count); inline Node(NodeId id, int input_count, int reserve_input_count);
typedef ZoneDeque<Input> InputDeque; typedef ZoneDeque<Input> InputDeque;
...@@ -204,17 +199,39 @@ class Node FINAL { ...@@ -204,17 +199,39 @@ class Node FINAL {
Mark mark() { return mark_; } Mark mark() { return mark_; }
void set_mark(Mark mark) { mark_ = mark; } void set_mark(Mark mark) { mark_ = mark; }
static const int kReservedInputCountBits = 2; int input_count() const { return InputCountField::decode(bit_field_); }
static const int kMaxReservedInputs = (1 << kReservedInputCountBits) - 1; void set_input_count(int input_count) {
static const int kDefaultReservedInputs = kMaxReservedInputs; DCHECK_LE(0, input_count);
bit_field_ = InputCountField::update(bit_field_, input_count);
}
int reserved_input_count() const {
return ReservedInputCountField::decode(bit_field_);
}
void set_reserved_input_count(int reserved_input_count) {
DCHECK_LE(0, reserved_input_count);
bit_field_ =
ReservedInputCountField::update(bit_field_, reserved_input_count);
}
bool has_appendable_inputs() const {
return HasAppendableInputsField::decode(bit_field_);
}
void set_has_appendable_inputs(bool has_appendable_inputs) {
bit_field_ =
HasAppendableInputsField::update(bit_field_, has_appendable_inputs);
}
typedef BitField<unsigned, 0, 29> InputCountField;
typedef BitField<unsigned, 29, 2> ReservedInputCountField;
typedef BitField<unsigned, 31, 1> HasAppendableInputsField;
static const int kDefaultReservedInputs = ReservedInputCountField::kMax;
const Operator* op_; const Operator* op_;
Bounds bounds_; Bounds bounds_;
Mark mark_; Mark mark_;
NodeId id_; NodeId id_;
int input_count_ : 29; unsigned bit_field_;
unsigned int reserve_input_count_ : kReservedInputCountBits;
bool has_appendable_inputs_ : 1;
union { union {
// When a node is initially allocated, it uses a static buffer to hold its // 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. // inputs under the assumption that the number of outputs will not increase.
...@@ -223,7 +240,6 @@ class Node FINAL { ...@@ -223,7 +240,6 @@ class Node FINAL {
Input* static_; Input* static_;
InputDeque* appendable_; InputDeque* appendable_;
} inputs_; } inputs_;
int use_count_;
Use* first_use_; Use* first_use_;
Use* last_use_; Use* last_use_;
...@@ -240,7 +256,7 @@ class Edge { ...@@ -240,7 +256,7 @@ class Edge {
Node* to() const { return input_->to; } Node* to() const { return input_->to; }
int index() const { int index() const {
int index = input_->use->input_index; int index = input_->use->input_index;
DCHECK(index < input_->use->from->input_count_); DCHECK(index < input_->use->from->input_count());
return index; return index;
} }
...@@ -500,8 +516,6 @@ inline void Node::ReplaceUses(Node* replace_to) { ...@@ -500,8 +516,6 @@ inline void Node::ReplaceUses(Node* replace_to) {
first_use_->prev = replace_to->last_use_; first_use_->prev = replace_to->last_use_;
replace_to->last_use_ = last_use_; replace_to->last_use_ = last_use_;
} }
replace_to->use_count_ += use_count_;
use_count_ = 0;
first_use_ = NULL; first_use_ = NULL;
last_use_ = NULL; last_use_ = NULL;
} }
...@@ -526,16 +540,16 @@ inline void Node::RemoveAllInputs() { ...@@ -526,16 +540,16 @@ inline void Node::RemoveAllInputs() {
} }
inline void Node::TrimInputCount(int new_input_count) { inline void Node::TrimInputCount(int new_input_count) {
if (new_input_count == input_count_) return; // Nothing to do. if (new_input_count == input_count()) return; // Nothing to do.
DCHECK(new_input_count < input_count_); DCHECK(new_input_count < input_count());
// Update inline inputs. // Update inline inputs.
for (int i = new_input_count; i < input_count_; i++) { for (int i = new_input_count; i < input_count(); i++) {
Node::Input* input = GetInputRecordPtr(i); Node::Input* input = GetInputRecordPtr(i);
input->Update(NULL); input->Update(NULL);
} }
input_count_ = new_input_count; set_input_count(new_input_count);
} }
inline void Node::ReplaceInput(int index, Node* new_to) { inline void Node::ReplaceInput(int index, Node* new_to) {
...@@ -561,14 +575,14 @@ inline void Node::Input::Update(Node* new_to) { ...@@ -561,14 +575,14 @@ inline void Node::Input::Update(Node* new_to) {
} }
inline void Node::EnsureAppendableInputs(Zone* zone) { inline void Node::EnsureAppendableInputs(Zone* zone) {
if (!has_appendable_inputs_) { if (!has_appendable_inputs()) {
void* deque_buffer = zone->New(sizeof(InputDeque)); void* deque_buffer = zone->New(sizeof(InputDeque));
InputDeque* deque = new (deque_buffer) InputDeque(zone); InputDeque* deque = new (deque_buffer) InputDeque(zone);
for (int i = 0; i < input_count_; ++i) { for (int i = 0; i < input_count(); ++i) {
deque->push_back(inputs_.static_[i]); deque->push_back(inputs_.static_[i]);
} }
inputs_.appendable_ = deque; inputs_.appendable_ = deque;
has_appendable_inputs_ = true; set_has_appendable_inputs(true);
} }
} }
...@@ -577,18 +591,18 @@ inline void Node::AppendInput(Zone* zone, Node* to_append) { ...@@ -577,18 +591,18 @@ inline void Node::AppendInput(Zone* zone, Node* to_append) {
Input new_input; Input new_input;
new_input.to = to_append; new_input.to = to_append;
new_input.use = new_use; new_input.use = new_use;
if (reserve_input_count_ > 0) { if (reserved_input_count() > 0) {
DCHECK(!has_appendable_inputs_); DCHECK(!has_appendable_inputs());
reserve_input_count_--; set_reserved_input_count(reserved_input_count() - 1);
inputs_.static_[input_count_] = new_input; inputs_.static_[input_count()] = new_input;
} else { } else {
EnsureAppendableInputs(zone); EnsureAppendableInputs(zone);
inputs_.appendable_->push_back(new_input); inputs_.appendable_->push_back(new_input);
} }
new_use->input_index = input_count_; new_use->input_index = input_count();
new_use->from = this; new_use->from = this;
to_append->AppendUse(new_use); to_append->AppendUse(new_use);
input_count_++; set_input_count(input_count() + 1);
} }
inline void Node::InsertInput(Zone* zone, int index, Node* to_insert) { inline void Node::InsertInput(Zone* zone, int index, Node* to_insert) {
...@@ -619,7 +633,6 @@ inline void Node::AppendUse(Use* use) { ...@@ -619,7 +633,6 @@ inline void Node::AppendUse(Use* use) {
last_use_->next = use; last_use_->next = use;
} }
last_use_ = use; last_use_ = use;
++use_count_;
} }
inline void Node::RemoveUse(Use* use) { inline void Node::RemoveUse(Use* use) {
...@@ -634,7 +647,6 @@ inline void Node::RemoveUse(Use* use) { ...@@ -634,7 +647,6 @@ inline void Node::RemoveUse(Use* use) {
if (use->next != NULL) { if (use->next != NULL) {
use->next->prev = use->prev; use->next->prev = use->prev;
} }
--use_count_;
} }
inline bool Node::OwnedBy(Node* owner) const { inline bool Node::OwnedBy(Node* owner) const {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment