| 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 |