OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/simplified-lowering.h" | 5 #include "src/compiler/simplified-lowering.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 | 147 |
148 UseInfo UseInfoForBasePointer(const FieldAccess& access) { | 148 UseInfo UseInfoForBasePointer(const FieldAccess& access) { |
149 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt(); | 149 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt(); |
150 } | 150 } |
151 | 151 |
152 | 152 |
153 UseInfo UseInfoForBasePointer(const ElementAccess& access) { | 153 UseInfo UseInfoForBasePointer(const ElementAccess& access) { |
154 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt(); | 154 return access.tag() != 0 ? UseInfo::AnyTagged() : UseInfo::PointerInt(); |
155 } | 155 } |
156 | 156 |
| 157 |
| 158 #ifdef DEBUG |
| 159 // Helpers for monotonicity checking. |
| 160 |
| 161 bool MachineTypeIsSubtype(MachineType t1, MachineType t2) { |
| 162 switch (t1) { |
| 163 case kMachNone: |
| 164 return true; |
| 165 case kTypeBool: |
| 166 return t2 == kTypeBool || t2 == kTypeNumber || t2 == kTypeAny; |
| 167 case kTypeInt32: |
| 168 return t2 == kTypeInt32 || t2 == kTypeNumber || t2 == kTypeAny; |
| 169 case kTypeUint32: |
| 170 return t2 == kTypeUint32 || t2 == kTypeNumber || t2 == kTypeAny; |
| 171 case kTypeInt64: |
| 172 return t2 == kTypeInt64; |
| 173 case kTypeUint64: |
| 174 return t2 == kTypeUint64; |
| 175 case kTypeNumber: |
| 176 return t2 == kTypeNumber || t2 == kTypeAny; |
| 177 case kTypeAny: |
| 178 return t2 == kTypeAny; |
| 179 default: |
| 180 break; |
| 181 } |
| 182 UNREACHABLE(); |
| 183 return false; |
| 184 } |
| 185 |
| 186 |
| 187 bool MachineRepresentationIsSubtype(MachineType r1, MachineType r2) { |
| 188 switch (r1) { |
| 189 case kMachNone: |
| 190 return true; |
| 191 case kRepBit: |
| 192 return r2 == kRepBit || r2 == kRepTagged; |
| 193 case kRepWord8: |
| 194 return r2 == kRepWord8 || r2 == kRepWord16 || r2 == kRepWord32 || |
| 195 r2 == kRepWord64 || r2 == kRepFloat32 || r2 == kRepFloat64 || |
| 196 r2 == kRepTagged; |
| 197 case kRepWord16: |
| 198 return r2 == kRepWord16 || r2 == kRepWord32 || r2 == kRepWord64 || |
| 199 r2 == kRepFloat32 || r2 == kRepFloat64 || r2 == kRepTagged; |
| 200 case kRepWord32: |
| 201 return r2 == kRepWord32 || r2 == kRepWord64 || r2 == kRepFloat64 || |
| 202 r2 == kRepTagged; |
| 203 case kRepWord64: |
| 204 return r2 == kRepWord64; |
| 205 case kRepFloat32: |
| 206 return r2 == kRepFloat32 || r2 == kRepFloat64 || r2 == kRepTagged; |
| 207 case kRepFloat64: |
| 208 return r2 == kRepFloat64 || r2 == kRepTagged; |
| 209 case kRepTagged: |
| 210 return r2 == kRepTagged; |
| 211 default: |
| 212 break; |
| 213 } |
| 214 UNREACHABLE(); |
| 215 return false; |
| 216 } |
| 217 |
| 218 |
| 219 bool MachineTypeRepIsSubtype(MachineTypeUnion m1, MachineTypeUnion m2) { |
| 220 return MachineTypeIsSubtype(static_cast<MachineType>(m1 & kTypeMask), |
| 221 static_cast<MachineType>(m2 & kTypeMask)) && |
| 222 MachineRepresentationIsSubtype( |
| 223 static_cast<MachineType>(m1 & kRepMask), |
| 224 static_cast<MachineType>(m2 & kRepMask)); |
| 225 } |
| 226 |
| 227 |
| 228 class InputUseInfos { |
| 229 public: |
| 230 explicit InputUseInfos(Zone* zone) : input_use_infos_(zone) {} |
| 231 |
| 232 void SetAndCheckInput(Node* node, int index, UseInfo use_info) { |
| 233 if (input_use_infos_.empty()) { |
| 234 input_use_infos_.resize(node->InputCount(), UseInfo::None()); |
| 235 } |
| 236 // Check that the new use informatin is a super-type of the old |
| 237 // one. |
| 238 CHECK(IsUseLessGeneral(input_use_infos_[index], use_info)); |
| 239 input_use_infos_[index] = use_info; |
| 240 } |
| 241 |
| 242 private: |
| 243 ZoneVector<UseInfo> input_use_infos_; |
| 244 |
| 245 static bool IsUseLessGeneral(UseInfo use1, UseInfo use2) { |
| 246 return MachineRepresentationIsSubtype(use1.preferred(), use2.preferred()) && |
| 247 use1.truncation().IsLessGeneralThan(use2.truncation()); |
| 248 } |
| 249 }; |
| 250 |
| 251 #endif // DEBUG |
| 252 |
157 } // namespace | 253 } // namespace |
158 | 254 |
159 | 255 |
160 class RepresentationSelector { | 256 class RepresentationSelector { |
161 public: | 257 public: |
162 // Information for each node tracked during the fixpoint. | 258 // Information for each node tracked during the fixpoint. |
163 class NodeInfo { | 259 class NodeInfo { |
164 public: | 260 public: |
165 // Adds new use to the node. Returns true if something has changed | 261 // Adds new use to the node. Returns true if something has changed |
166 // and the node has to be requeued. | 262 // and the node has to be requeued. |
(...skipping 17 matching lines...) Expand all Loading... |
184 MachineTypeUnion output_ = kMachNone; // Output type of the node. | 280 MachineTypeUnion output_ = kMachNone; // Output type of the node. |
185 Truncation truncation_ = Truncation::None(); // Information about uses. | 281 Truncation truncation_ = Truncation::None(); // Information about uses. |
186 }; | 282 }; |
187 | 283 |
188 RepresentationSelector(JSGraph* jsgraph, Zone* zone, | 284 RepresentationSelector(JSGraph* jsgraph, Zone* zone, |
189 RepresentationChanger* changer, | 285 RepresentationChanger* changer, |
190 SourcePositionTable* source_positions) | 286 SourcePositionTable* source_positions) |
191 : jsgraph_(jsgraph), | 287 : jsgraph_(jsgraph), |
192 count_(jsgraph->graph()->NodeCount()), | 288 count_(jsgraph->graph()->NodeCount()), |
193 info_(count_, zone), | 289 info_(count_, zone), |
| 290 #ifdef DEBUG |
| 291 node_input_use_infos_(count_, InputUseInfos(zone), zone), |
| 292 #endif |
194 nodes_(zone), | 293 nodes_(zone), |
195 replacements_(zone), | 294 replacements_(zone), |
196 phase_(PROPAGATE), | 295 phase_(PROPAGATE), |
197 changer_(changer), | 296 changer_(changer), |
198 queue_(zone), | 297 queue_(zone), |
199 source_positions_(source_positions), | 298 source_positions_(source_positions), |
200 type_cache_(TypeCache::Get()) {} | 299 type_cache_(TypeCache::Get()) { |
| 300 } |
201 | 301 |
202 void Run(SimplifiedLowering* lowering) { | 302 void Run(SimplifiedLowering* lowering) { |
203 // Run propagation phase to a fixpoint. | 303 // Run propagation phase to a fixpoint. |
204 TRACE("--{Propagation phase}--\n"); | 304 TRACE("--{Propagation phase}--\n"); |
205 phase_ = PROPAGATE; | 305 phase_ = PROPAGATE; |
206 Enqueue(jsgraph_->graph()->end()); | 306 EnqueueInitial(jsgraph_->graph()->end()); |
207 // Process nodes from the queue until it is empty. | 307 // Process nodes from the queue until it is empty. |
208 while (!queue_.empty()) { | 308 while (!queue_.empty()) { |
209 Node* node = queue_.front(); | 309 Node* node = queue_.front(); |
210 NodeInfo* info = GetInfo(node); | 310 NodeInfo* info = GetInfo(node); |
211 queue_.pop(); | 311 queue_.pop(); |
212 info->set_queued(false); | 312 info->set_queued(false); |
213 TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic()); | 313 TRACE(" visit #%d: %s\n", node->id(), node->op()->mnemonic()); |
214 VisitNode(node, info->truncation(), NULL); | 314 VisitNode(node, info->truncation(), NULL); |
215 TRACE(" ==> output "); | 315 TRACE(" ==> output "); |
216 PrintInfo(info->output_type()); | 316 PrintInfo(info->output_type()); |
(...skipping 21 matching lines...) Expand all Loading... |
238 Node* replacement = *(++i); | 338 Node* replacement = *(++i); |
239 node->ReplaceUses(replacement); | 339 node->ReplaceUses(replacement); |
240 // We also need to replace the node in the rest of the vector. | 340 // We also need to replace the node in the rest of the vector. |
241 for (NodeVector::iterator j = i + 1; j != replacements_.end(); ++j) { | 341 for (NodeVector::iterator j = i + 1; j != replacements_.end(); ++j) { |
242 ++j; | 342 ++j; |
243 if (*j == node) *j = replacement; | 343 if (*j == node) *j = replacement; |
244 } | 344 } |
245 } | 345 } |
246 } | 346 } |
247 | 347 |
248 // Enqueue {node} if the {use} contains new information for that node. | 348 void EnqueueInitial(Node* node) { |
249 // Add {node} to {nodes_} if this is the first time it's been visited. | 349 NodeInfo* info = GetInfo(node); |
250 void Enqueue(Node* node, UseInfo use_info = UseInfo::None()) { | 350 info->set_visited(); |
| 351 info->set_queued(true); |
| 352 nodes_.push_back(node); |
| 353 queue_.push(node); |
| 354 } |
| 355 |
| 356 // Enqueue {use_node}'s {index} input if the {use} contains new information |
| 357 // for that input node. Add the input to {nodes_} if this is the first time |
| 358 // it's been visited. |
| 359 void EnqueueInput(Node* use_node, int index, |
| 360 UseInfo use_info = UseInfo::None()) { |
| 361 Node* node = use_node->InputAt(index); |
251 if (phase_ != PROPAGATE) return; | 362 if (phase_ != PROPAGATE) return; |
252 NodeInfo* info = GetInfo(node); | 363 NodeInfo* info = GetInfo(node); |
| 364 #ifdef DEBUG |
| 365 // Check monotonicity of input requirements. |
| 366 node_input_use_infos_[use_node->id()].SetAndCheckInput(use_node, index, |
| 367 use_info); |
| 368 #endif // DEBUG |
253 if (!info->visited()) { | 369 if (!info->visited()) { |
254 // First visit of this node. | 370 // First visit of this node. |
255 info->set_visited(); | 371 info->set_visited(); |
256 info->set_queued(true); | 372 info->set_queued(true); |
257 nodes_.push_back(node); | 373 nodes_.push_back(node); |
258 queue_.push(node); | 374 queue_.push(node); |
259 TRACE(" initial: "); | 375 TRACE(" initial: "); |
260 info->AddUse(use_info); | 376 info->AddUse(use_info); |
261 PrintTruncation(info->truncation()); | 377 PrintTruncation(info->truncation()); |
262 return; | 378 return; |
(...skipping 14 matching lines...) Expand all Loading... |
277 } | 393 } |
278 | 394 |
279 bool lower() { return phase_ == LOWER; } | 395 bool lower() { return phase_ == LOWER; } |
280 | 396 |
281 void SetOutput(Node* node, MachineTypeUnion output) { | 397 void SetOutput(Node* node, MachineTypeUnion output) { |
282 // Every node should have at most one output representation. Note that | 398 // Every node should have at most one output representation. Note that |
283 // phis can have 0, if they have not been used in a representation-inducing | 399 // phis can have 0, if they have not been used in a representation-inducing |
284 // instruction. | 400 // instruction. |
285 DCHECK((output & kRepMask) == 0 || | 401 DCHECK((output & kRepMask) == 0 || |
286 base::bits::IsPowerOfTwo32(output & kRepMask)); | 402 base::bits::IsPowerOfTwo32(output & kRepMask)); |
287 GetInfo(node)->set_output_type(output); | 403 NodeInfo* info = GetInfo(node); |
| 404 DCHECK(MachineTypeRepIsSubtype(info->output_type(), output)); |
| 405 info->set_output_type(output); |
288 } | 406 } |
289 | 407 |
290 bool BothInputsAre(Node* node, Type* type) { | 408 bool BothInputsAre(Node* node, Type* type) { |
291 DCHECK_EQ(2, node->InputCount()); | 409 DCHECK_EQ(2, node->InputCount()); |
292 return NodeProperties::GetType(node->InputAt(0))->Is(type) && | 410 return NodeProperties::GetType(node->InputAt(0))->Is(type) && |
293 NodeProperties::GetType(node->InputAt(1))->Is(type); | 411 NodeProperties::GetType(node->InputAt(1))->Is(type); |
294 } | 412 } |
295 | 413 |
296 void EnqueueInputUse(Node* node, int index, UseInfo use) { | |
297 Enqueue(node->InputAt(index), use); | |
298 } | |
299 | |
300 void ConvertInput(Node* node, int index, UseInfo use) { | 414 void ConvertInput(Node* node, int index, UseInfo use) { |
301 Node* input = node->InputAt(index); | 415 Node* input = node->InputAt(index); |
302 // In the change phase, insert a change before the use if necessary. | 416 // In the change phase, insert a change before the use if necessary. |
303 if (use.preferred() == kMachNone) | 417 if (use.preferred() == kMachNone) |
304 return; // No input requirement on the use. | 418 return; // No input requirement on the use. |
305 MachineTypeUnion output = GetInfo(input)->output_type(); | 419 MachineTypeUnion output = GetInfo(input)->output_type(); |
306 if ((output & kRepMask) != use.preferred()) { | 420 if ((output & kRepMask) != use.preferred()) { |
307 // Output representation doesn't match usage. | 421 // Output representation doesn't match usage. |
308 TRACE(" change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(), | 422 TRACE(" change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(), |
309 index, input->id(), input->op()->mnemonic()); | 423 index, input->id(), input->op()->mnemonic()); |
310 TRACE(" from "); | 424 TRACE(" from "); |
311 PrintInfo(output); | 425 PrintInfo(output); |
312 TRACE(" to "); | 426 TRACE(" to "); |
313 PrintUseInfo(use); | 427 PrintUseInfo(use); |
314 TRACE("\n"); | 428 TRACE("\n"); |
315 Node* n = changer_->GetRepresentationFor(input, output, use.preferred(), | 429 Node* n = changer_->GetRepresentationFor(input, output, use.preferred(), |
316 use.truncation()); | 430 use.truncation()); |
317 node->ReplaceInput(index, n); | 431 node->ReplaceInput(index, n); |
318 } | 432 } |
319 } | 433 } |
320 | 434 |
321 void ProcessInput(Node* node, int index, UseInfo use) { | 435 void ProcessInput(Node* node, int index, UseInfo use) { |
322 if (phase_ == PROPAGATE) { | 436 if (phase_ == PROPAGATE) { |
323 EnqueueInputUse(node, index, use); | 437 EnqueueInput(node, index, use); |
324 } else { | 438 } else { |
325 ConvertInput(node, index, use); | 439 ConvertInput(node, index, use); |
326 } | 440 } |
327 } | 441 } |
328 | 442 |
329 void ProcessRemainingInputs(Node* node, int index) { | 443 void ProcessRemainingInputs(Node* node, int index) { |
330 DCHECK_GE(index, NodeProperties::PastValueIndex(node)); | 444 DCHECK_GE(index, NodeProperties::PastValueIndex(node)); |
331 DCHECK_GE(index, NodeProperties::PastContextIndex(node)); | 445 DCHECK_GE(index, NodeProperties::PastContextIndex(node)); |
332 for (int i = std::max(index, NodeProperties::FirstEffectIndex(node)); | 446 for (int i = std::max(index, NodeProperties::FirstEffectIndex(node)); |
333 i < NodeProperties::PastEffectIndex(node); ++i) { | 447 i < NodeProperties::PastEffectIndex(node); ++i) { |
334 Enqueue(node->InputAt(i)); // Effect inputs: just visit | 448 EnqueueInput(node, i); // Effect inputs: just visit |
335 } | 449 } |
336 for (int i = std::max(index, NodeProperties::FirstControlIndex(node)); | 450 for (int i = std::max(index, NodeProperties::FirstControlIndex(node)); |
337 i < NodeProperties::PastControlIndex(node); ++i) { | 451 i < NodeProperties::PastControlIndex(node); ++i) { |
338 Enqueue(node->InputAt(i)); // Control inputs: just visit | 452 EnqueueInput(node, i); // Control inputs: just visit |
339 } | 453 } |
340 } | 454 } |
341 | 455 |
342 // The default, most general visitation case. For {node}, process all value, | 456 // The default, most general visitation case. For {node}, process all value, |
343 // context, frame state, effect, and control inputs, assuming that value | 457 // context, frame state, effect, and control inputs, assuming that value |
344 // inputs should have {kRepTagged} representation and can observe all output | 458 // inputs should have {kRepTagged} representation and can observe all output |
345 // values {kTypeAny}. | 459 // values {kTypeAny}. |
346 void VisitInputs(Node* node) { | 460 void VisitInputs(Node* node) { |
347 int tagged_count = node->op()->ValueInputCount() + | 461 int tagged_count = node->op()->ValueInputCount() + |
348 OperatorProperties::GetContextInputCount(node->op()); | 462 OperatorProperties::GetContextInputCount(node->op()); |
349 // Visit value and context inputs as tagged. | 463 // Visit value and context inputs as tagged. |
350 for (int i = 0; i < tagged_count; i++) { | 464 for (int i = 0; i < tagged_count; i++) { |
351 ProcessInput(node, i, UseInfo::AnyTagged()); | 465 ProcessInput(node, i, UseInfo::AnyTagged()); |
352 } | 466 } |
353 // Only enqueue other inputs (framestates, effects, control). | 467 // Only enqueue other inputs (framestates, effects, control). |
354 for (int i = tagged_count; i < node->InputCount(); i++) { | 468 for (int i = tagged_count; i < node->InputCount(); i++) { |
355 Enqueue(node->InputAt(i)); | 469 EnqueueInput(node, i); |
356 } | 470 } |
357 // Assume the output is tagged. | |
358 SetOutput(node, kMachAnyTagged); | |
359 } | 471 } |
360 | 472 |
361 // Helper for binops of the R x L -> O variety. | 473 // Helper for binops of the R x L -> O variety. |
362 void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use, | 474 void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use, |
363 MachineTypeUnion output) { | 475 MachineTypeUnion output) { |
364 DCHECK_EQ(2, node->op()->ValueInputCount()); | 476 DCHECK_EQ(2, node->op()->ValueInputCount()); |
365 ProcessInput(node, 0, left_use); | 477 ProcessInput(node, 0, left_use); |
366 ProcessInput(node, 1, right_use); | 478 ProcessInput(node, 1, right_use); |
367 for (int i = 2; i < node->InputCount(); i++) { | 479 for (int i = 2; i < node->InputCount(); i++) { |
368 Enqueue(node->InputAt(i)); | 480 EnqueueInput(node, i); |
369 } | 481 } |
370 SetOutput(node, output); | 482 SetOutput(node, output); |
371 } | 483 } |
372 | 484 |
373 // Helper for binops of the I x I -> O variety. | 485 // Helper for binops of the I x I -> O variety. |
374 void VisitBinop(Node* node, UseInfo input_use, MachineTypeUnion output) { | 486 void VisitBinop(Node* node, UseInfo input_use, MachineTypeUnion output) { |
375 VisitBinop(node, input_use, input_use, output); | 487 VisitBinop(node, input_use, input_use, output); |
376 } | 488 } |
377 | 489 |
378 // Helper for unops of the I -> O variety. | 490 // Helper for unops of the I -> O variety. |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
516 if (sig->return_count() > 0) { | 628 if (sig->return_count() > 0) { |
517 SetOutput(node, desc->GetMachineSignature()->GetReturn()); | 629 SetOutput(node, desc->GetMachineSignature()->GetReturn()); |
518 } else { | 630 } else { |
519 SetOutput(node, kMachAnyTagged); | 631 SetOutput(node, kMachAnyTagged); |
520 } | 632 } |
521 } | 633 } |
522 | 634 |
523 void VisitStateValues(Node* node) { | 635 void VisitStateValues(Node* node) { |
524 if (phase_ == PROPAGATE) { | 636 if (phase_ == PROPAGATE) { |
525 for (int i = 0; i < node->InputCount(); i++) { | 637 for (int i = 0; i < node->InputCount(); i++) { |
526 Enqueue(node->InputAt(i), UseInfo::Any()); | 638 EnqueueInput(node, i, UseInfo::Any()); |
527 } | 639 } |
528 } else { | 640 } else { |
529 Zone* zone = jsgraph_->zone(); | 641 Zone* zone = jsgraph_->zone(); |
530 ZoneVector<MachineType>* types = | 642 ZoneVector<MachineType>* types = |
531 new (zone->New(sizeof(ZoneVector<MachineType>))) | 643 new (zone->New(sizeof(ZoneVector<MachineType>))) |
532 ZoneVector<MachineType>(node->InputCount(), zone); | 644 ZoneVector<MachineType>(node->InputCount(), zone); |
533 for (int i = 0; i < node->InputCount(); i++) { | 645 for (int i = 0; i < node->InputCount(); i++) { |
534 MachineTypeUnion input_type = GetInfo(node->InputAt(i))->output_type(); | 646 MachineTypeUnion input_type = GetInfo(node->InputAt(i))->output_type(); |
535 (*types)[i] = static_cast<MachineType>(input_type); | 647 (*types)[i] = static_cast<MachineType>(input_type); |
536 } | 648 } |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
606 return VisitLeaf(node, kRepFloat64); | 718 return VisitLeaf(node, kRepFloat64); |
607 case IrOpcode::kExternalConstant: | 719 case IrOpcode::kExternalConstant: |
608 return VisitLeaf(node, kMachPtr); | 720 return VisitLeaf(node, kMachPtr); |
609 case IrOpcode::kNumberConstant: | 721 case IrOpcode::kNumberConstant: |
610 return VisitLeaf(node, kRepTagged); | 722 return VisitLeaf(node, kRepTagged); |
611 case IrOpcode::kHeapConstant: | 723 case IrOpcode::kHeapConstant: |
612 return VisitLeaf(node, kRepTagged); | 724 return VisitLeaf(node, kRepTagged); |
613 | 725 |
614 case IrOpcode::kBranch: | 726 case IrOpcode::kBranch: |
615 ProcessInput(node, 0, UseInfo::Bool()); | 727 ProcessInput(node, 0, UseInfo::Bool()); |
616 Enqueue(NodeProperties::GetControlInput(node, 0)); | 728 EnqueueInput(node, NodeProperties::FirstControlIndex(node)); |
617 break; | 729 break; |
618 case IrOpcode::kSwitch: | 730 case IrOpcode::kSwitch: |
619 ProcessInput(node, 0, UseInfo::TruncatingWord32()); | 731 ProcessInput(node, 0, UseInfo::TruncatingWord32()); |
620 Enqueue(NodeProperties::GetControlInput(node, 0)); | 732 EnqueueInput(node, NodeProperties::FirstControlIndex(node)); |
621 break; | 733 break; |
622 case IrOpcode::kSelect: | 734 case IrOpcode::kSelect: |
623 return VisitSelect(node, truncation, lowering); | 735 return VisitSelect(node, truncation, lowering); |
624 case IrOpcode::kPhi: | 736 case IrOpcode::kPhi: |
625 return VisitPhi(node, truncation, lowering); | 737 return VisitPhi(node, truncation, lowering); |
626 case IrOpcode::kCall: | 738 case IrOpcode::kCall: |
627 return VisitCall(node, lowering); | 739 return VisitCall(node, lowering); |
628 | 740 |
629 //------------------------------------------------------------------ | 741 //------------------------------------------------------------------ |
630 // JavaScript operators. | 742 // JavaScript operators. |
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1097 return VisitBinop(node, UseInfo::Float64(), UseInfo::TruncatingWord32(), | 1209 return VisitBinop(node, UseInfo::Float64(), UseInfo::TruncatingWord32(), |
1098 kMachFloat64); | 1210 kMachFloat64); |
1099 case IrOpcode::kLoadStackPointer: | 1211 case IrOpcode::kLoadStackPointer: |
1100 case IrOpcode::kLoadFramePointer: | 1212 case IrOpcode::kLoadFramePointer: |
1101 return VisitLeaf(node, kMachPtr); | 1213 return VisitLeaf(node, kMachPtr); |
1102 case IrOpcode::kStateValues: | 1214 case IrOpcode::kStateValues: |
1103 VisitStateValues(node); | 1215 VisitStateValues(node); |
1104 break; | 1216 break; |
1105 default: | 1217 default: |
1106 VisitInputs(node); | 1218 VisitInputs(node); |
| 1219 // Assume the output is tagged. |
| 1220 SetOutput(node, kMachAnyTagged); |
1107 break; | 1221 break; |
1108 } | 1222 } |
1109 } | 1223 } |
1110 | 1224 |
1111 void DeferReplacement(Node* node, Node* replacement) { | 1225 void DeferReplacement(Node* node, Node* replacement) { |
1112 TRACE("defer replacement #%d:%s with #%d:%s\n", node->id(), | 1226 TRACE("defer replacement #%d:%s with #%d:%s\n", node->id(), |
1113 node->op()->mnemonic(), replacement->id(), | 1227 node->op()->mnemonic(), replacement->id(), |
1114 replacement->op()->mnemonic()); | 1228 replacement->op()->mnemonic()); |
1115 | 1229 |
1116 if (replacement->id() < count_ && | 1230 if (replacement->id() < count_ && |
(...skipping 30 matching lines...) Expand all Loading... |
1147 if (FLAG_trace_representation) { | 1261 if (FLAG_trace_representation) { |
1148 OFStream os(stdout); | 1262 OFStream os(stdout); |
1149 os << info.preferred() << ":" << info.truncation().description(); | 1263 os << info.preferred() << ":" << info.truncation().description(); |
1150 } | 1264 } |
1151 } | 1265 } |
1152 | 1266 |
1153 private: | 1267 private: |
1154 JSGraph* jsgraph_; | 1268 JSGraph* jsgraph_; |
1155 size_t const count_; // number of nodes in the graph | 1269 size_t const count_; // number of nodes in the graph |
1156 ZoneVector<NodeInfo> info_; // node id -> usage information | 1270 ZoneVector<NodeInfo> info_; // node id -> usage information |
| 1271 #ifdef DEBUG |
| 1272 ZoneVector<InputUseInfos> node_input_use_infos_; // Debug information about |
| 1273 // requirements on inputs. |
| 1274 #endif // DEBUG |
1157 NodeVector nodes_; // collected nodes | 1275 NodeVector nodes_; // collected nodes |
1158 NodeVector replacements_; // replacements to be done after lowering | 1276 NodeVector replacements_; // replacements to be done after lowering |
1159 Phase phase_; // current phase of algorithm | 1277 Phase phase_; // current phase of algorithm |
1160 RepresentationChanger* changer_; // for inserting representation changes | 1278 RepresentationChanger* changer_; // for inserting representation changes |
1161 ZoneQueue<Node*> queue_; // queue for traversing the graph | 1279 ZoneQueue<Node*> queue_; // queue for traversing the graph |
1162 // TODO(danno): RepresentationSelector shouldn't know anything about the | 1280 // TODO(danno): RepresentationSelector shouldn't know anything about the |
1163 // source positions table, but must for now since there currently is no other | 1281 // source positions table, but must for now since there currently is no other |
1164 // way to pass down source position information to nodes created during | 1282 // way to pass down source position information to nodes created during |
1165 // lowering. Once this phase becomes a vanilla reducer, it should get source | 1283 // lowering. Once this phase becomes a vanilla reducer, it should get source |
1166 // position information via the SourcePositionWrapper like all other reducers. | 1284 // position information via the SourcePositionWrapper like all other reducers. |
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1610 ReplaceEffectUses(node, comparison); | 1728 ReplaceEffectUses(node, comparison); |
1611 node->ReplaceInput(0, comparison); | 1729 node->ReplaceInput(0, comparison); |
1612 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1730 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
1613 node->TrimInputCount(2); | 1731 node->TrimInputCount(2); |
1614 NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual()); | 1732 NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual()); |
1615 } | 1733 } |
1616 | 1734 |
1617 } // namespace compiler | 1735 } // namespace compiler |
1618 } // namespace internal | 1736 } // namespace internal |
1619 } // namespace v8 | 1737 } // namespace v8 |
OLD | NEW |