blob: 8f44c24fd2117018dc28d0181e046d1378611d94 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
3// found in the LICENSE file.
4
5#include "src/compiler/node.h"
6
Emily Bernierd0a1eb72015-03-24 16:35:39 -04007#include "src/compiler/graph.h"
8#include "src/zone.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +00009
10namespace v8 {
11namespace internal {
12namespace compiler {
13
Emily Bernierd0a1eb72015-03-24 16:35:39 -040014Node::Node(NodeId id, int input_count, int reserved_input_count)
15 : id_(id),
16 bit_field_(InputCountField::encode(input_count) |
17 ReservedInputCountField::encode(reserved_input_count) |
18 HasAppendableInputsField::encode(false)),
19 first_use_(nullptr),
20 last_use_(nullptr) {
21 inputs_.static_ = reinterpret_cast<Input*>(this + 1);
22}
23
24
25Node* Node::New(Graph* graph, int input_count, Node** inputs,
26 bool has_extensible_inputs) {
27 size_t node_size = sizeof(Node);
28 int reserve_input_count = has_extensible_inputs ? kDefaultReservedInputs : 0;
29 size_t inputs_size = (input_count + reserve_input_count) * sizeof(Input);
30 size_t uses_size = input_count * sizeof(Use);
31 int size = static_cast<int>(node_size + inputs_size + uses_size);
32 Zone* zone = graph->zone();
33 void* buffer = zone->New(size);
34 Node* result =
35 new (buffer) Node(graph->NextNodeID(), input_count, reserve_input_count);
36 Input* input =
37 reinterpret_cast<Input*>(reinterpret_cast<char*>(buffer) + node_size);
38 Use* use =
39 reinterpret_cast<Use*>(reinterpret_cast<char*>(input) + inputs_size);
40
41 for (int current = 0; current < input_count; ++current) {
42 Node* to = *inputs++;
43 input->to = to;
44 input->use = use;
45 use->input_index = current;
46 use->from = result;
47 to->AppendUse(use);
48 ++use;
49 ++input;
50 }
51 return result;
52}
53
54
Ben Murdochb8a8cc12014-11-26 15:28:44 +000055void Node::Kill() {
56 DCHECK_NOT_NULL(op());
57 RemoveAllInputs();
58 DCHECK(uses().empty());
59}
60
61
62void Node::CollectProjections(NodeVector* projections) {
63 for (size_t i = 0; i < projections->size(); i++) {
64 (*projections)[i] = NULL;
65 }
66 for (UseIter i = uses().begin(); i != uses().end(); ++i) {
67 if ((*i)->opcode() != IrOpcode::kProjection) continue;
68 size_t index = OpParameter<size_t>(*i);
69 DCHECK_LT(index, projections->size());
70 DCHECK_EQ(NULL, (*projections)[index]);
71 (*projections)[index] = *i;
72 }
73}
74
75
76Node* Node::FindProjection(size_t projection_index) {
77 for (UseIter i = uses().begin(); i != uses().end(); ++i) {
78 if ((*i)->opcode() == IrOpcode::kProjection &&
79 OpParameter<size_t>(*i) == projection_index) {
80 return *i;
81 }
82 }
83 return NULL;
84}
85
86
Emily Bernierd0a1eb72015-03-24 16:35:39 -040087int Node::UseCount() const {
88 int use_count = 0;
89 for (const Use* use = first_use_; use; use = use->next) {
90 ++use_count;
91 }
92 return use_count;
93}
Ben Murdochb8a8cc12014-11-26 15:28:44 +000094
95
Emily Bernierd0a1eb72015-03-24 16:35:39 -040096Node* Node::UseAt(int index) const {
97 DCHECK_LE(0, index);
98 DCHECK_LT(index, UseCount());
99 Use* current = first_use_;
100 while (index-- != 0) {
101 current = current->next;
102 }
103 return current->from;
104}
105
106
107std::ostream& operator<<(std::ostream& os, const Node& n) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000108 os << n.id() << ": " << *n.op();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400109 if (n.InputCount() > 0) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000110 os << "(";
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400111 for (int i = 0; i < n.InputCount(); ++i) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000112 if (i != 0) os << ", ";
113 os << n.InputAt(i)->id();
114 }
115 os << ")";
116 }
117 return os;
118}
119
120} // namespace compiler
121} // namespace internal
122} // namespace v8