OLD | NEW |
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 #include "src/compiler/node.h" | 5 #include "src/compiler/node.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 namespace v8 { | 9 namespace v8 { |
10 namespace internal { | 10 namespace internal { |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 | 111 |
112 int Node::UseCount() const { | 112 int Node::UseCount() const { |
113 int use_count = 0; | 113 int use_count = 0; |
114 for (const Use* use = first_use_; use; use = use->next) { | 114 for (const Use* use = first_use_; use; use = use->next) { |
115 ++use_count; | 115 ++use_count; |
116 } | 116 } |
117 return use_count; | 117 return use_count; |
118 } | 118 } |
119 | 119 |
120 | 120 |
121 Node* Node::UseAt(int index) const { | 121 void Node::ReplaceUses(Node* that) { |
122 DCHECK_LE(0, index); | 122 DCHECK(this->first_use_ == nullptr || this->first_use_->prev == nullptr); |
123 DCHECK_LT(index, UseCount()); | 123 DCHECK(that->first_use_ == nullptr || that->first_use_->prev == nullptr); |
124 const Use* use = first_use_; | 124 |
125 while (index-- != 0) { | 125 // Update the pointers to {this} to point to {that}. |
126 use = use->next; | 126 Use* last_use = nullptr; |
| 127 for (Use* use = this->first_use_; use; use = use->next) { |
| 128 use->from->GetInputRecordPtr(use->input_index)->to = that; |
| 129 last_use = use; |
127 } | 130 } |
128 return use->from; | 131 if (last_use) { |
| 132 // Concat the use list of {this} and {that}. |
| 133 last_use->next = that->first_use_; |
| 134 if (that->first_use_) that->first_use_->prev = last_use; |
| 135 that->first_use_ = this->first_use_; |
| 136 } |
| 137 first_use_ = nullptr; |
129 } | 138 } |
130 | 139 |
131 | 140 |
132 void Node::ReplaceUses(Node* replace_to) { | |
133 for (Use* use = first_use_; use; use = use->next) { | |
134 use->from->GetInputRecordPtr(use->input_index)->to = replace_to; | |
135 } | |
136 if (!replace_to->last_use_) { | |
137 DCHECK(!replace_to->first_use_); | |
138 replace_to->first_use_ = first_use_; | |
139 replace_to->last_use_ = last_use_; | |
140 } else if (first_use_) { | |
141 DCHECK_NOT_NULL(replace_to->first_use_); | |
142 replace_to->last_use_->next = first_use_; | |
143 first_use_->prev = replace_to->last_use_; | |
144 replace_to->last_use_ = last_use_; | |
145 } | |
146 first_use_ = nullptr; | |
147 last_use_ = nullptr; | |
148 } | |
149 | |
150 | |
151 void Node::Input::Update(Node* new_to) { | 141 void Node::Input::Update(Node* new_to) { |
152 Node* old_to = this->to; | 142 Node* old_to = this->to; |
153 if (new_to == old_to) return; // Nothing to do. | 143 if (new_to == old_to) return; // Nothing to do. |
154 // Snip out the use from where it used to be | 144 // Snip out the use from where it used to be |
155 if (old_to) { | 145 if (old_to) { |
156 old_to->RemoveUse(use); | 146 old_to->RemoveUse(use); |
157 } | 147 } |
158 to = new_to; | 148 to = new_to; |
159 // And put it into the new node's use list. | 149 // And put it into the new node's use list. |
160 if (new_to) { | 150 if (new_to) { |
161 new_to->AppendUse(use); | 151 new_to->AppendUse(use); |
162 } else { | 152 } else { |
163 use->next = nullptr; | 153 use->next = nullptr; |
164 use->prev = nullptr; | 154 use->prev = nullptr; |
165 } | 155 } |
166 } | 156 } |
167 | 157 |
168 | 158 |
169 Node::Node(NodeId id, const Operator* op, int input_count, | 159 Node::Node(NodeId id, const Operator* op, int input_count, |
170 int reserved_input_count) | 160 int reserved_input_count) |
171 : op_(op), | 161 : op_(op), |
172 mark_(0), | 162 mark_(0), |
173 id_(id), | 163 id_(id), |
174 bit_field_(InputCountField::encode(input_count) | | 164 bit_field_(InputCountField::encode(input_count) | |
175 ReservedInputCountField::encode(reserved_input_count) | | 165 ReservedInputCountField::encode(reserved_input_count) | |
176 HasAppendableInputsField::encode(false)), | 166 HasAppendableInputsField::encode(false)), |
177 first_use_(nullptr), | 167 first_use_(nullptr) {} |
178 last_use_(nullptr) {} | |
179 | 168 |
180 | 169 |
181 void Node::EnsureAppendableInputs(Zone* zone) { | 170 void Node::EnsureAppendableInputs(Zone* zone) { |
182 if (!has_appendable_inputs()) { | 171 if (!has_appendable_inputs()) { |
183 void* deque_buffer = zone->New(sizeof(InputDeque)); | 172 void* deque_buffer = zone->New(sizeof(InputDeque)); |
184 InputDeque* deque = new (deque_buffer) InputDeque(zone); | 173 InputDeque* deque = new (deque_buffer) InputDeque(zone); |
185 for (int i = 0; i < input_count(); ++i) { | 174 for (int i = 0; i < input_count(); ++i) { |
186 deque->push_back(inputs_.static_[i]); | 175 deque->push_back(inputs_.static_[i]); |
187 } | 176 } |
188 inputs_.appendable_ = deque; | 177 inputs_.appendable_ = deque; |
189 set_has_appendable_inputs(true); | 178 set_has_appendable_inputs(true); |
190 } | 179 } |
191 } | 180 } |
192 | 181 |
193 | 182 |
194 void Node::AppendUse(Use* const use) { | 183 void Node::AppendUse(Use* const use) { |
195 use->next = nullptr; | 184 DCHECK(first_use_ == nullptr || first_use_->prev == nullptr); |
196 use->prev = last_use_; | 185 use->next = first_use_; |
197 if (last_use_) { | 186 use->prev = nullptr; |
198 last_use_->next = use; | 187 if (first_use_) first_use_->prev = use; |
199 } else { | 188 first_use_ = use; |
200 first_use_ = use; | |
201 } | |
202 last_use_ = use; | |
203 } | 189 } |
204 | 190 |
205 | 191 |
206 void Node::RemoveUse(Use* const use) { | 192 void Node::RemoveUse(Use* const use) { |
207 if (use == last_use_) { | 193 DCHECK(first_use_ == nullptr || first_use_->prev == nullptr); |
208 last_use_ = use->prev; | |
209 } | |
210 if (use->prev) { | 194 if (use->prev) { |
| 195 DCHECK_NE(first_use_, use); |
211 use->prev->next = use->next; | 196 use->prev->next = use->next; |
212 } else { | 197 } else { |
| 198 DCHECK_EQ(first_use_, use); |
213 first_use_ = use->next; | 199 first_use_ = use->next; |
214 } | 200 } |
215 if (use->next) { | 201 if (use->next) { |
216 use->next->prev = use->prev; | 202 use->next->prev = use->prev; |
217 } | 203 } |
218 } | 204 } |
219 | 205 |
220 | 206 |
221 std::ostream& operator<<(std::ostream& os, const Node& n) { | 207 std::ostream& operator<<(std::ostream& os, const Node& n) { |
222 os << n.id() << ": " << *n.op(); | 208 os << n.id() << ": " << *n.op(); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
267 ++(*this); | 253 ++(*this); |
268 return result; | 254 return result; |
269 } | 255 } |
270 | 256 |
271 | 257 |
272 bool Node::Uses::empty() const { return begin() == end(); } | 258 bool Node::Uses::empty() const { return begin() == end(); } |
273 | 259 |
274 } // namespace compiler | 260 } // namespace compiler |
275 } // namespace internal | 261 } // namespace internal |
276 } // namespace v8 | 262 } // namespace v8 |
OLD | NEW |