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 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 }; | 235 }; |
236 | 236 |
237 #endif // DEBUG | 237 #endif // DEBUG |
238 | 238 |
239 } // namespace | 239 } // namespace |
240 | 240 |
241 | 241 |
242 class RepresentationSelector { | 242 class RepresentationSelector { |
243 public: | 243 public: |
244 // Information for each node tracked during the fixpoint. | 244 // Information for each node tracked during the fixpoint. |
245 class NodeOutputInfo { | |
246 public: | |
247 NodeOutputInfo(MachineRepresentation representation, Type* type) | |
248 : type_(type), representation_(representation) {} | |
249 NodeOutputInfo() | |
250 : type_(Type::None()), representation_(MachineRepresentation::kNone) {} | |
251 | |
252 MachineRepresentation representation() const { return representation_; } | |
253 Type* type() const { return type_; } | |
254 | |
255 static NodeOutputInfo None() { | |
256 return NodeOutputInfo(MachineRepresentation::kNone, Type::None()); | |
257 } | |
258 | |
259 static NodeOutputInfo Float32() { | |
260 return NodeOutputInfo(MachineRepresentation::kFloat32, Type::Number()); | |
261 } | |
262 | |
263 static NodeOutputInfo Float64() { | |
264 return NodeOutputInfo(MachineRepresentation::kFloat64, Type::Number()); | |
265 } | |
266 | |
267 static NodeOutputInfo NumberTruncatedToWord32() { | |
268 return NodeOutputInfo(MachineRepresentation::kWord32, Type::Number()); | |
269 } | |
270 | |
271 static NodeOutputInfo Int32() { | |
272 return NodeOutputInfo(MachineRepresentation::kWord32, Type::Signed32()); | |
273 } | |
274 | |
275 static NodeOutputInfo Uint32() { | |
276 return NodeOutputInfo(MachineRepresentation::kWord32, Type::Unsigned32()); | |
277 } | |
278 | |
279 static NodeOutputInfo Bool() { | |
280 return NodeOutputInfo(MachineRepresentation::kBit, Type::Boolean()); | |
281 } | |
282 | |
283 static NodeOutputInfo Int64() { | |
284 // TODO(jarin) Fix once we have a real int64 type. | |
285 return NodeOutputInfo(MachineRepresentation::kWord64, Type::Internal()); | |
286 } | |
287 | |
288 static NodeOutputInfo Uint64() { | |
289 // TODO(jarin) Fix once we have a real uint64 type. | |
290 return NodeOutputInfo(MachineRepresentation::kWord64, Type::Internal()); | |
291 } | |
292 | |
293 static NodeOutputInfo AnyTagged() { | |
294 return NodeOutputInfo(MachineRepresentation::kTagged, Type::Any()); | |
295 } | |
296 | |
297 static NodeOutputInfo BoolTagged() { | |
298 return NodeOutputInfo(MachineRepresentation::kTagged, Type::Boolean()); | |
299 } | |
300 | |
301 static NodeOutputInfo NumberTagged() { | |
302 return NodeOutputInfo(MachineRepresentation::kTagged, Type::Number()); | |
303 } | |
304 | |
305 static NodeOutputInfo Pointer() { | |
306 return NodeOutputInfo(MachineType::PointerRepresentation(), Type::Any()); | |
307 } | |
308 | |
309 private: | |
310 Type* type_; | |
311 MachineRepresentation representation_; | |
312 }; | |
313 | |
314 class NodeInfo { | 245 class NodeInfo { |
315 public: | 246 public: |
316 // Adds new use to the node. Returns true if something has changed | 247 // Adds new use to the node. Returns true if something has changed |
317 // and the node has to be requeued. | 248 // and the node has to be requeued. |
318 bool AddUse(UseInfo info) { | 249 bool AddUse(UseInfo info) { |
319 Truncation old_truncation = truncation_; | 250 Truncation old_truncation = truncation_; |
320 truncation_ = Truncation::Generalize(truncation_, info.truncation()); | 251 truncation_ = Truncation::Generalize(truncation_, info.truncation()); |
321 return truncation_ != old_truncation; | 252 return truncation_ != old_truncation; |
322 } | 253 } |
323 | 254 |
324 void set_queued(bool value) { queued_ = value; } | 255 void set_queued(bool value) { queued_ = value; } |
325 bool queued() const { return queued_; } | 256 bool queued() const { return queued_; } |
326 void set_visited() { visited_ = true; } | 257 void set_visited() { visited_ = true; } |
327 bool visited() const { return visited_; } | 258 bool visited() const { return visited_; } |
328 Truncation truncation() const { return truncation_; } | 259 Truncation truncation() const { return truncation_; } |
329 void set_output_type(NodeOutputInfo output) { output_ = output; } | 260 void set_output(MachineRepresentation output) { representation_ = output; } |
330 | 261 |
331 Type* output_type() const { return output_.type(); } | 262 MachineRepresentation representation() const { return representation_; } |
332 MachineRepresentation representation() const { | |
333 return output_.representation(); | |
334 } | |
335 | 263 |
336 private: | 264 private: |
337 bool queued_ = false; // Bookkeeping for the traversal. | 265 bool queued_ = false; // Bookkeeping for the traversal. |
338 bool visited_ = false; // Bookkeeping for the traversal. | 266 bool visited_ = false; // Bookkeeping for the traversal. |
339 NodeOutputInfo output_; // Output type and representation. | 267 MachineRepresentation representation_ = |
| 268 MachineRepresentation::kNone; // Output representation. |
340 Truncation truncation_ = Truncation::None(); // Information about uses. | 269 Truncation truncation_ = Truncation::None(); // Information about uses. |
341 }; | 270 }; |
342 | 271 |
343 RepresentationSelector(JSGraph* jsgraph, Zone* zone, | 272 RepresentationSelector(JSGraph* jsgraph, Zone* zone, |
344 RepresentationChanger* changer, | 273 RepresentationChanger* changer, |
345 SourcePositionTable* source_positions) | 274 SourcePositionTable* source_positions) |
346 : jsgraph_(jsgraph), | 275 : jsgraph_(jsgraph), |
347 count_(jsgraph->graph()->NodeCount()), | 276 count_(jsgraph->graph()->NodeCount()), |
348 info_(count_, zone), | 277 info_(count_, zone), |
349 #ifdef DEBUG | 278 #ifdef DEBUG |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
464 // the end and it has not been queued yet. | 393 // the end and it has not been queued yet. |
465 if (info->visited() && !info->queued()) { | 394 if (info->visited() && !info->queued()) { |
466 queue_.push(user); | 395 queue_.push(user); |
467 info->set_queued(true); | 396 info->set_queued(true); |
468 } | 397 } |
469 } | 398 } |
470 } | 399 } |
471 } | 400 } |
472 } | 401 } |
473 | 402 |
474 void SetOutputFromMachineType(Node* node, MachineType machine_type) { | 403 void SetOutput(Node* node, MachineRepresentation representation) { |
475 Type* type = Type::None(); | 404 NodeInfo* info = GetInfo(node); |
476 switch (machine_type.semantic()) { | 405 DCHECK( |
477 case MachineSemantic::kNone: | 406 MachineRepresentationIsSubtype(info->representation(), representation)); |
478 type = Type::None(); | 407 info->set_output(representation); |
479 break; | |
480 case MachineSemantic::kBool: | |
481 type = Type::Boolean(); | |
482 break; | |
483 case MachineSemantic::kInt32: | |
484 type = Type::Signed32(); | |
485 break; | |
486 case MachineSemantic::kUint32: | |
487 type = Type::Unsigned32(); | |
488 break; | |
489 case MachineSemantic::kInt64: | |
490 // TODO(jarin) Fix once we have proper int64. | |
491 type = Type::Internal(); | |
492 break; | |
493 case MachineSemantic::kUint64: | |
494 // TODO(jarin) Fix once we have proper uint64. | |
495 type = Type::Internal(); | |
496 break; | |
497 case MachineSemantic::kNumber: | |
498 type = Type::Number(); | |
499 break; | |
500 case MachineSemantic::kAny: | |
501 type = Type::Any(); | |
502 break; | |
503 } | |
504 return SetOutput(node, NodeOutputInfo(machine_type.representation(), type)); | |
505 } | 408 } |
506 | 409 |
507 void SetOutput(Node* node, NodeOutputInfo output_info) { | 410 Type* GetUpperBound(Node* node) { return NodeProperties::GetType(node); } |
508 // Every node should have at most one output representation. Note that | |
509 // phis can have 0, if they have not been used in a representation-inducing | |
510 // instruction. | |
511 Type* output_type = output_info.type(); | |
512 if (NodeProperties::IsTyped(node)) { | |
513 output_type = Type::Intersect(NodeProperties::GetType(node), | |
514 output_info.type(), jsgraph_->zone()); | |
515 } | |
516 NodeInfo* info = GetInfo(node); | |
517 DCHECK(info->output_type()->Is(output_type)); | |
518 DCHECK(MachineRepresentationIsSubtype(info->representation(), | |
519 output_info.representation())); | |
520 if (!output_type->Is(info->output_type()) || | |
521 output_info.representation() != info->representation()) { | |
522 EnqueueUses(node); | |
523 } | |
524 info->set_output_type( | |
525 NodeOutputInfo(output_info.representation(), output_type)); | |
526 } | |
527 | 411 |
528 bool BothInputsAreSigned32(Node* node) { | 412 bool BothInputsAreSigned32(Node* node) { |
529 DCHECK_EQ(2, node->InputCount()); | 413 DCHECK_EQ(2, node->InputCount()); |
530 return GetInfo(node->InputAt(0))->output_type()->Is(Type::Signed32()) && | 414 return GetUpperBound(node->InputAt(0))->Is(Type::Signed32()) && |
531 GetInfo(node->InputAt(1))->output_type()->Is(Type::Signed32()); | 415 GetUpperBound(node->InputAt(1))->Is(Type::Signed32()); |
532 } | 416 } |
533 | 417 |
534 bool BothInputsAreUnsigned32(Node* node) { | 418 bool BothInputsAreUnsigned32(Node* node) { |
535 DCHECK_EQ(2, node->InputCount()); | 419 DCHECK_EQ(2, node->InputCount()); |
536 return GetInfo(node->InputAt(0))->output_type()->Is(Type::Unsigned32()) && | 420 return GetUpperBound(node->InputAt(0))->Is(Type::Unsigned32()) && |
537 GetInfo(node->InputAt(1))->output_type()->Is(Type::Unsigned32()); | 421 GetUpperBound(node->InputAt(1))->Is(Type::Unsigned32()); |
538 } | 422 } |
539 | 423 |
540 bool BothInputsAre(Node* node, Type* type) { | 424 bool BothInputsAre(Node* node, Type* type) { |
541 DCHECK_EQ(2, node->InputCount()); | 425 DCHECK_EQ(2, node->InputCount()); |
542 return GetInfo(node->InputAt(0))->output_type()->Is(type) && | 426 return GetUpperBound(node->InputAt(0))->Is(type) && |
543 GetInfo(node->InputAt(1))->output_type()->Is(type); | 427 GetUpperBound(node->InputAt(1))->Is(type); |
544 } | 428 } |
545 | 429 |
546 void ConvertInput(Node* node, int index, UseInfo use) { | 430 void ConvertInput(Node* node, int index, UseInfo use) { |
547 Node* input = node->InputAt(index); | 431 Node* input = node->InputAt(index); |
548 // In the change phase, insert a change before the use if necessary. | 432 // In the change phase, insert a change before the use if necessary. |
549 if (use.preferred() == MachineRepresentation::kNone) | 433 if (use.preferred() == MachineRepresentation::kNone) |
550 return; // No input requirement on the use. | 434 return; // No input requirement on the use. |
551 NodeInfo* input_info = GetInfo(input); | 435 NodeInfo* input_info = GetInfo(input); |
552 MachineRepresentation input_rep = input_info->representation(); | 436 MachineRepresentation input_rep = input_info->representation(); |
553 if (input_rep != use.preferred()) { | 437 if (input_rep != use.preferred()) { |
554 // Output representation doesn't match usage. | 438 // Output representation doesn't match usage. |
555 TRACE(" change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(), | 439 TRACE(" change: #%d:%s(@%d #%d:%s) ", node->id(), node->op()->mnemonic(), |
556 index, input->id(), input->op()->mnemonic()); | 440 index, input->id(), input->op()->mnemonic()); |
557 TRACE(" from "); | 441 TRACE(" from "); |
558 PrintOutputInfo(input_info); | 442 PrintOutputInfo(input_info); |
559 TRACE(" to "); | 443 TRACE(" to "); |
560 PrintUseInfo(use); | 444 PrintUseInfo(use); |
561 TRACE("\n"); | 445 TRACE("\n"); |
562 Node* n = changer_->GetRepresentationFor( | 446 Node* n = changer_->GetRepresentationFor( |
563 input, input_info->representation(), input_info->output_type(), | 447 input, input_info->representation(), GetUpperBound(input), |
564 use.preferred(), use.truncation()); | 448 use.preferred(), use.truncation()); |
565 node->ReplaceInput(index, n); | 449 node->ReplaceInput(index, n); |
566 } | 450 } |
567 } | 451 } |
568 | 452 |
569 void ProcessInput(Node* node, int index, UseInfo use) { | 453 void ProcessInput(Node* node, int index, UseInfo use) { |
570 if (phase_ == PROPAGATE) { | 454 if (phase_ == PROPAGATE) { |
571 EnqueueInput(node, index, use); | 455 EnqueueInput(node, index, use); |
572 } else { | 456 } else { |
573 ConvertInput(node, index, use); | 457 ConvertInput(node, index, use); |
(...skipping 25 matching lines...) Expand all Loading... |
599 ProcessInput(node, i, UseInfo::AnyTagged()); | 483 ProcessInput(node, i, UseInfo::AnyTagged()); |
600 } | 484 } |
601 // Only enqueue other inputs (framestates, effects, control). | 485 // Only enqueue other inputs (framestates, effects, control). |
602 for (int i = tagged_count; i < node->InputCount(); i++) { | 486 for (int i = tagged_count; i < node->InputCount(); i++) { |
603 EnqueueInput(node, i); | 487 EnqueueInput(node, i); |
604 } | 488 } |
605 } | 489 } |
606 | 490 |
607 // Helper for binops of the R x L -> O variety. | 491 // Helper for binops of the R x L -> O variety. |
608 void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use, | 492 void VisitBinop(Node* node, UseInfo left_use, UseInfo right_use, |
609 NodeOutputInfo output) { | 493 MachineRepresentation output) { |
610 DCHECK_EQ(2, node->op()->ValueInputCount()); | 494 DCHECK_EQ(2, node->op()->ValueInputCount()); |
611 ProcessInput(node, 0, left_use); | 495 ProcessInput(node, 0, left_use); |
612 ProcessInput(node, 1, right_use); | 496 ProcessInput(node, 1, right_use); |
613 for (int i = 2; i < node->InputCount(); i++) { | 497 for (int i = 2; i < node->InputCount(); i++) { |
614 EnqueueInput(node, i); | 498 EnqueueInput(node, i); |
615 } | 499 } |
616 SetOutput(node, output); | 500 SetOutput(node, output); |
617 } | 501 } |
618 | 502 |
619 // Helper for binops of the I x I -> O variety. | 503 // Helper for binops of the I x I -> O variety. |
620 void VisitBinop(Node* node, UseInfo input_use, NodeOutputInfo output) { | 504 void VisitBinop(Node* node, UseInfo input_use, MachineRepresentation output) { |
621 VisitBinop(node, input_use, input_use, output); | 505 VisitBinop(node, input_use, input_use, output); |
622 } | 506 } |
623 | 507 |
624 // Helper for unops of the I -> O variety. | 508 // Helper for unops of the I -> O variety. |
625 void VisitUnop(Node* node, UseInfo input_use, NodeOutputInfo output) { | 509 void VisitUnop(Node* node, UseInfo input_use, MachineRepresentation output) { |
626 DCHECK_EQ(1, node->InputCount()); | 510 DCHECK_EQ(1, node->InputCount()); |
627 ProcessInput(node, 0, input_use); | 511 ProcessInput(node, 0, input_use); |
628 SetOutput(node, output); | 512 SetOutput(node, output); |
629 } | 513 } |
630 | 514 |
631 // Helper for leaf nodes. | 515 // Helper for leaf nodes. |
632 void VisitLeaf(Node* node, NodeOutputInfo output) { | 516 void VisitLeaf(Node* node, MachineRepresentation output) { |
633 DCHECK_EQ(0, node->InputCount()); | 517 DCHECK_EQ(0, node->InputCount()); |
634 SetOutput(node, output); | 518 SetOutput(node, output); |
635 } | 519 } |
636 | 520 |
637 // Helpers for specific types of binops. | 521 // Helpers for specific types of binops. |
638 void VisitFloat64Binop(Node* node) { | 522 void VisitFloat64Binop(Node* node) { |
639 VisitBinop(node, UseInfo::Float64(), NodeOutputInfo::Float64()); | 523 VisitBinop(node, UseInfo::Float64(), MachineRepresentation::kFloat64); |
640 } | 524 } |
641 void VisitInt32Binop(Node* node) { | 525 void VisitInt32Binop(Node* node) { |
642 VisitBinop(node, UseInfo::TruncatingWord32(), NodeOutputInfo::Int32()); | 526 VisitBinop(node, UseInfo::TruncatingWord32(), |
| 527 MachineRepresentation::kWord32); |
643 } | 528 } |
644 void VisitWord32TruncatingBinop(Node* node) { | 529 void VisitWord32TruncatingBinop(Node* node) { |
645 VisitBinop(node, UseInfo::TruncatingWord32(), | 530 VisitBinop(node, UseInfo::TruncatingWord32(), |
646 NodeOutputInfo::NumberTruncatedToWord32()); | 531 MachineRepresentation::kWord32); |
647 } | 532 } |
648 void VisitUint32Binop(Node* node) { | 533 void VisitUint32Binop(Node* node) { |
649 VisitBinop(node, UseInfo::TruncatingWord32(), NodeOutputInfo::Uint32()); | 534 VisitBinop(node, UseInfo::TruncatingWord32(), |
| 535 MachineRepresentation::kWord32); |
650 } | 536 } |
651 void VisitInt64Binop(Node* node) { | 537 void VisitInt64Binop(Node* node) { |
652 VisitBinop(node, UseInfo::TruncatingWord64(), NodeOutputInfo::Int64()); | 538 VisitBinop(node, UseInfo::TruncatingWord64(), |
| 539 MachineRepresentation::kWord64); |
653 } | 540 } |
654 void VisitUint64Binop(Node* node) { | 541 void VisitUint64Binop(Node* node) { |
655 VisitBinop(node, UseInfo::TruncatingWord64(), NodeOutputInfo::Uint64()); | 542 VisitBinop(node, UseInfo::TruncatingWord64(), |
| 543 MachineRepresentation::kWord64); |
656 } | 544 } |
657 void VisitFloat64Cmp(Node* node) { | 545 void VisitFloat64Cmp(Node* node) { |
658 VisitBinop(node, UseInfo::Float64(), NodeOutputInfo::Bool()); | 546 VisitBinop(node, UseInfo::Float64(), MachineRepresentation::kBit); |
659 } | 547 } |
660 void VisitInt32Cmp(Node* node) { | 548 void VisitInt32Cmp(Node* node) { |
661 VisitBinop(node, UseInfo::TruncatingWord32(), NodeOutputInfo::Bool()); | 549 VisitBinop(node, UseInfo::TruncatingWord32(), MachineRepresentation::kBit); |
662 } | 550 } |
663 void VisitUint32Cmp(Node* node) { | 551 void VisitUint32Cmp(Node* node) { |
664 VisitBinop(node, UseInfo::TruncatingWord32(), NodeOutputInfo::Bool()); | 552 VisitBinop(node, UseInfo::TruncatingWord32(), MachineRepresentation::kBit); |
665 } | 553 } |
666 void VisitInt64Cmp(Node* node) { | 554 void VisitInt64Cmp(Node* node) { |
667 VisitBinop(node, UseInfo::TruncatingWord64(), NodeOutputInfo::Bool()); | 555 VisitBinop(node, UseInfo::TruncatingWord64(), MachineRepresentation::kBit); |
668 } | 556 } |
669 void VisitUint64Cmp(Node* node) { | 557 void VisitUint64Cmp(Node* node) { |
670 VisitBinop(node, UseInfo::TruncatingWord64(), NodeOutputInfo::Bool()); | 558 VisitBinop(node, UseInfo::TruncatingWord64(), MachineRepresentation::kBit); |
671 } | 559 } |
672 | 560 |
673 // Infer representation for phi-like nodes. | 561 // Infer representation for phi-like nodes. |
674 NodeOutputInfo GetOutputInfoForPhi(Node* node, Truncation use) { | 562 MachineRepresentation GetOutputInfoForPhi(Node* node, Truncation use) { |
675 // Compute the type. | |
676 Type* type = GetInfo(node->InputAt(0))->output_type(); | |
677 for (int i = 1; i < node->op()->ValueInputCount(); ++i) { | |
678 type = Type::Union(type, GetInfo(node->InputAt(i))->output_type(), | |
679 jsgraph_->zone()); | |
680 } | |
681 | |
682 // Compute the representation. | 563 // Compute the representation. |
683 MachineRepresentation rep = MachineRepresentation::kTagged; | 564 Type* type = GetUpperBound(node); |
684 if (type->Is(Type::None())) { | 565 if (type->Is(Type::None())) { |
685 rep = MachineRepresentation::kNone; | 566 return MachineRepresentation::kNone; |
686 } else if (type->Is(Type::Signed32()) || type->Is(Type::Unsigned32())) { | 567 } else if (type->Is(Type::Signed32()) || type->Is(Type::Unsigned32())) { |
687 rep = MachineRepresentation::kWord32; | 568 return MachineRepresentation::kWord32; |
688 } else if (use.TruncatesToWord32()) { | 569 } else if (use.TruncatesToWord32()) { |
689 rep = MachineRepresentation::kWord32; | 570 return MachineRepresentation::kWord32; |
690 } else if (type->Is(Type::Boolean())) { | 571 } else if (type->Is(Type::Boolean())) { |
691 rep = MachineRepresentation::kBit; | 572 return MachineRepresentation::kBit; |
692 } else if (type->Is(Type::Number())) { | 573 } else if (type->Is(Type::Number())) { |
693 rep = MachineRepresentation::kFloat64; | 574 return MachineRepresentation::kFloat64; |
694 } else if (type->Is(Type::Internal())) { | 575 } else if (type->Is(Type::Internal())) { |
695 // We mark (u)int64 as Type::Internal. | 576 // We mark (u)int64 as Type::Internal. |
696 // TODO(jarin) This is a workaround for our lack of (u)int64 | 577 // TODO(jarin) This is a workaround for our lack of (u)int64 |
697 // types. This can be removed once we can represent (u)int64 | 578 // types. This can be removed once we can represent (u)int64 |
698 // unambiguously. (At the moment internal objects, such as the hole, | 579 // unambiguously. (At the moment internal objects, such as the hole, |
699 // are also Type::Internal()). | 580 // are also Type::Internal()). |
700 bool is_word64 = GetInfo(node->InputAt(0))->representation() == | 581 bool is_word64 = GetInfo(node->InputAt(0))->representation() == |
701 MachineRepresentation::kWord64; | 582 MachineRepresentation::kWord64; |
702 #ifdef DEBUG | 583 #ifdef DEBUG |
703 // Check that all the inputs agree on being Word64. | 584 // Check that all the inputs agree on being Word64. |
704 for (int i = 1; i < node->op()->ValueInputCount(); i++) { | 585 for (int i = 1; i < node->op()->ValueInputCount(); i++) { |
705 DCHECK_EQ(is_word64, GetInfo(node->InputAt(i))->representation() == | 586 DCHECK_EQ(is_word64, GetInfo(node->InputAt(i))->representation() == |
706 MachineRepresentation::kWord64); | 587 MachineRepresentation::kWord64); |
707 } | 588 } |
708 #endif | 589 #endif |
709 rep = is_word64 ? MachineRepresentation::kWord64 | 590 return is_word64 ? MachineRepresentation::kWord64 |
710 : MachineRepresentation::kTagged; | 591 : MachineRepresentation::kTagged; |
711 } | 592 } |
712 return NodeOutputInfo(rep, type); | 593 return MachineRepresentation::kTagged; |
713 } | 594 } |
714 | 595 |
715 // Helper for handling selects. | 596 // Helper for handling selects. |
716 void VisitSelect(Node* node, Truncation truncation, | 597 void VisitSelect(Node* node, Truncation truncation, |
717 SimplifiedLowering* lowering) { | 598 SimplifiedLowering* lowering) { |
718 ProcessInput(node, 0, UseInfo::Bool()); | 599 ProcessInput(node, 0, UseInfo::Bool()); |
719 | 600 |
720 NodeOutputInfo output = GetOutputInfoForPhi(node, truncation); | 601 MachineRepresentation output = GetOutputInfoForPhi(node, truncation); |
721 SetOutput(node, output); | 602 SetOutput(node, output); |
722 | 603 |
723 if (lower()) { | 604 if (lower()) { |
724 // Update the select operator. | 605 // Update the select operator. |
725 SelectParameters p = SelectParametersOf(node->op()); | 606 SelectParameters p = SelectParametersOf(node->op()); |
726 if (output.representation() != p.representation()) { | 607 if (output != p.representation()) { |
727 NodeProperties::ChangeOp(node, lowering->common()->Select( | 608 NodeProperties::ChangeOp(node, |
728 output.representation(), p.hint())); | 609 lowering->common()->Select(output, p.hint())); |
729 } | 610 } |
730 } | 611 } |
731 // Convert inputs to the output representation of this phi, pass the | 612 // Convert inputs to the output representation of this phi, pass the |
732 // truncation truncation along. | 613 // truncation truncation along. |
733 UseInfo input_use(output.representation(), truncation); | 614 UseInfo input_use(output, truncation); |
734 ProcessInput(node, 1, input_use); | 615 ProcessInput(node, 1, input_use); |
735 ProcessInput(node, 2, input_use); | 616 ProcessInput(node, 2, input_use); |
736 } | 617 } |
737 | 618 |
738 // Helper for handling phis. | 619 // Helper for handling phis. |
739 void VisitPhi(Node* node, Truncation truncation, | 620 void VisitPhi(Node* node, Truncation truncation, |
740 SimplifiedLowering* lowering) { | 621 SimplifiedLowering* lowering) { |
741 NodeOutputInfo output = GetOutputInfoForPhi(node, truncation); | 622 MachineRepresentation output = GetOutputInfoForPhi(node, truncation); |
742 SetOutput(node, output); | 623 SetOutput(node, output); |
743 | 624 |
744 int values = node->op()->ValueInputCount(); | 625 int values = node->op()->ValueInputCount(); |
745 if (lower()) { | 626 if (lower()) { |
746 // Update the phi operator. | 627 // Update the phi operator. |
747 if (output.representation() != PhiRepresentationOf(node->op())) { | 628 if (output != PhiRepresentationOf(node->op())) { |
748 NodeProperties::ChangeOp( | 629 NodeProperties::ChangeOp(node, lowering->common()->Phi(output, values)); |
749 node, lowering->common()->Phi(output.representation(), values)); | |
750 } | 630 } |
751 } | 631 } |
752 | 632 |
753 // Convert inputs to the output representation of this phi, pass the | 633 // Convert inputs to the output representation of this phi, pass the |
754 // truncation truncation along. | 634 // truncation truncation along. |
755 UseInfo input_use(output.representation(), truncation); | 635 UseInfo input_use(output, truncation); |
756 for (int i = 0; i < node->InputCount(); i++) { | 636 for (int i = 0; i < node->InputCount(); i++) { |
757 ProcessInput(node, i, i < values ? input_use : UseInfo::None()); | 637 ProcessInput(node, i, i < values ? input_use : UseInfo::None()); |
758 } | 638 } |
759 } | 639 } |
760 | 640 |
761 void VisitCall(Node* node, SimplifiedLowering* lowering) { | 641 void VisitCall(Node* node, SimplifiedLowering* lowering) { |
762 const CallDescriptor* desc = OpParameter<const CallDescriptor*>(node->op()); | 642 const CallDescriptor* desc = OpParameter<const CallDescriptor*>(node->op()); |
763 const MachineSignature* sig = desc->GetMachineSignature(); | 643 const MachineSignature* sig = desc->GetMachineSignature(); |
764 int params = static_cast<int>(sig->parameter_count()); | 644 int params = static_cast<int>(sig->parameter_count()); |
765 // Propagate representation information from call descriptor. | 645 // Propagate representation information from call descriptor. |
766 for (int i = 0; i < node->InputCount(); i++) { | 646 for (int i = 0; i < node->InputCount(); i++) { |
767 if (i == 0) { | 647 if (i == 0) { |
768 // The target of the call. | 648 // The target of the call. |
769 ProcessInput(node, i, UseInfo::None()); | 649 ProcessInput(node, i, UseInfo::None()); |
770 } else if ((i - 1) < params) { | 650 } else if ((i - 1) < params) { |
771 ProcessInput(node, i, TruncatingUseInfoFromRepresentation( | 651 ProcessInput(node, i, TruncatingUseInfoFromRepresentation( |
772 sig->GetParam(i - 1).representation())); | 652 sig->GetParam(i - 1).representation())); |
773 } else { | 653 } else { |
774 ProcessInput(node, i, UseInfo::None()); | 654 ProcessInput(node, i, UseInfo::None()); |
775 } | 655 } |
776 } | 656 } |
777 | 657 |
778 if (sig->return_count() > 0) { | 658 if (sig->return_count() > 0) { |
779 SetOutputFromMachineType(node, desc->GetMachineSignature()->GetReturn()); | 659 SetOutput(node, |
| 660 desc->GetMachineSignature()->GetReturn().representation()); |
780 } else { | 661 } else { |
781 SetOutput(node, NodeOutputInfo::AnyTagged()); | 662 SetOutput(node, MachineRepresentation::kTagged); |
782 } | 663 } |
783 } | 664 } |
784 | 665 |
785 MachineSemantic DeoptValueSemanticOf(Type* type) { | 666 MachineSemantic DeoptValueSemanticOf(Type* type) { |
786 CHECK(!type->Is(Type::None())); | 667 CHECK(!type->Is(Type::None())); |
787 // We only need signedness to do deopt correctly. | 668 // We only need signedness to do deopt correctly. |
788 if (type->Is(Type::Signed32())) { | 669 if (type->Is(Type::Signed32())) { |
789 return MachineSemantic::kInt32; | 670 return MachineSemantic::kInt32; |
790 } else if (type->Is(Type::Unsigned32())) { | 671 } else if (type->Is(Type::Unsigned32())) { |
791 return MachineSemantic::kUint32; | 672 return MachineSemantic::kUint32; |
792 } else { | 673 } else { |
793 return MachineSemantic::kAny; | 674 return MachineSemantic::kAny; |
794 } | 675 } |
795 } | 676 } |
796 | 677 |
797 void VisitStateValues(Node* node) { | 678 void VisitStateValues(Node* node) { |
798 if (phase_ == PROPAGATE) { | 679 if (phase_ == PROPAGATE) { |
799 for (int i = 0; i < node->InputCount(); i++) { | 680 for (int i = 0; i < node->InputCount(); i++) { |
800 EnqueueInput(node, i, UseInfo::Any()); | 681 EnqueueInput(node, i, UseInfo::Any()); |
801 } | 682 } |
802 } else { | 683 } else { |
803 Zone* zone = jsgraph_->zone(); | 684 Zone* zone = jsgraph_->zone(); |
804 ZoneVector<MachineType>* types = | 685 ZoneVector<MachineType>* types = |
805 new (zone->New(sizeof(ZoneVector<MachineType>))) | 686 new (zone->New(sizeof(ZoneVector<MachineType>))) |
806 ZoneVector<MachineType>(node->InputCount(), zone); | 687 ZoneVector<MachineType>(node->InputCount(), zone); |
807 for (int i = 0; i < node->InputCount(); i++) { | 688 for (int i = 0; i < node->InputCount(); i++) { |
808 NodeInfo* input_info = GetInfo(node->InputAt(i)); | 689 Node* input = node->InputAt(i); |
809 MachineType machine_type( | 690 NodeInfo* input_info = GetInfo(input); |
810 input_info->representation(), | 691 MachineType machine_type(input_info->representation(), |
811 DeoptValueSemanticOf(input_info->output_type())); | 692 DeoptValueSemanticOf(GetUpperBound(input))); |
812 DCHECK(machine_type.representation() != | 693 DCHECK(machine_type.representation() != |
813 MachineRepresentation::kWord32 || | 694 MachineRepresentation::kWord32 || |
814 machine_type.semantic() == MachineSemantic::kInt32 || | 695 machine_type.semantic() == MachineSemantic::kInt32 || |
815 machine_type.semantic() == MachineSemantic::kUint32); | 696 machine_type.semantic() == MachineSemantic::kUint32); |
816 (*types)[i] = machine_type; | 697 (*types)[i] = machine_type; |
817 } | 698 } |
818 NodeProperties::ChangeOp(node, | 699 NodeProperties::ChangeOp(node, |
819 jsgraph_->common()->TypedStateValues(types)); | 700 jsgraph_->common()->TypedStateValues(types)); |
820 } | 701 } |
821 SetOutput(node, NodeOutputInfo::AnyTagged()); | 702 SetOutput(node, MachineRepresentation::kTagged); |
822 } | 703 } |
823 | 704 |
824 const Operator* Int32Op(Node* node) { | 705 const Operator* Int32Op(Node* node) { |
825 return changer_->Int32OperatorFor(node->opcode()); | 706 return changer_->Int32OperatorFor(node->opcode()); |
826 } | 707 } |
827 | 708 |
828 const Operator* Uint32Op(Node* node) { | 709 const Operator* Uint32Op(Node* node) { |
829 return changer_->Uint32OperatorFor(node->opcode()); | 710 return changer_->Uint32OperatorFor(node->opcode()); |
830 } | 711 } |
831 | 712 |
832 const Operator* Float64Op(Node* node) { | 713 const Operator* Float64Op(Node* node) { |
833 return changer_->Float64OperatorFor(node->opcode()); | 714 return changer_->Float64OperatorFor(node->opcode()); |
834 } | 715 } |
835 | 716 |
836 // Dispatching routine for visiting the node {node} with the usage {use}. | 717 // Dispatching routine for visiting the node {node} with the usage {use}. |
837 // Depending on the operator, propagate new usage info to the inputs. | 718 // Depending on the operator, propagate new usage info to the inputs. |
838 void VisitNode(Node* node, Truncation truncation, | 719 void VisitNode(Node* node, Truncation truncation, |
839 SimplifiedLowering* lowering) { | 720 SimplifiedLowering* lowering) { |
840 switch (node->opcode()) { | 721 switch (node->opcode()) { |
841 //------------------------------------------------------------------ | 722 //------------------------------------------------------------------ |
842 // Common operators. | 723 // Common operators. |
843 //------------------------------------------------------------------ | 724 //------------------------------------------------------------------ |
844 case IrOpcode::kStart: | 725 case IrOpcode::kStart: |
845 case IrOpcode::kDead: | 726 case IrOpcode::kDead: |
846 return VisitLeaf(node, NodeOutputInfo::None()); | 727 return VisitLeaf(node, MachineRepresentation::kNone); |
847 case IrOpcode::kParameter: { | 728 case IrOpcode::kParameter: { |
848 // TODO(titzer): use representation from linkage. | 729 // TODO(titzer): use representation from linkage. |
849 Type* type = NodeProperties::GetType(node); | |
850 ProcessInput(node, 0, UseInfo::None()); | 730 ProcessInput(node, 0, UseInfo::None()); |
851 SetOutput(node, NodeOutputInfo(MachineRepresentation::kTagged, type)); | 731 SetOutput(node, MachineRepresentation::kTagged); |
852 return; | 732 return; |
853 } | 733 } |
854 case IrOpcode::kInt32Constant: | 734 case IrOpcode::kInt32Constant: |
855 return VisitLeaf(node, NodeOutputInfo::Int32()); | 735 return VisitLeaf(node, MachineRepresentation::kWord32); |
856 case IrOpcode::kInt64Constant: | 736 case IrOpcode::kInt64Constant: |
857 return VisitLeaf(node, NodeOutputInfo::Int64()); | 737 return VisitLeaf(node, MachineRepresentation::kWord64); |
858 case IrOpcode::kFloat32Constant: | 738 case IrOpcode::kFloat32Constant: |
859 return VisitLeaf(node, NodeOutputInfo::Float32()); | 739 return VisitLeaf(node, MachineRepresentation::kFloat32); |
860 case IrOpcode::kFloat64Constant: | 740 case IrOpcode::kFloat64Constant: |
861 return VisitLeaf(node, NodeOutputInfo::Float64()); | 741 return VisitLeaf(node, MachineRepresentation::kFloat64); |
862 case IrOpcode::kExternalConstant: | 742 case IrOpcode::kExternalConstant: |
863 return VisitLeaf(node, NodeOutputInfo::Pointer()); | 743 return VisitLeaf(node, MachineType::PointerRepresentation()); |
864 case IrOpcode::kNumberConstant: | 744 case IrOpcode::kNumberConstant: |
865 return VisitLeaf(node, NodeOutputInfo::NumberTagged()); | 745 return VisitLeaf(node, MachineRepresentation::kTagged); |
866 case IrOpcode::kHeapConstant: | 746 case IrOpcode::kHeapConstant: |
867 return VisitLeaf(node, NodeOutputInfo::AnyTagged()); | 747 return VisitLeaf(node, MachineRepresentation::kTagged); |
868 | 748 |
869 case IrOpcode::kDeoptimizeIf: | 749 case IrOpcode::kDeoptimizeIf: |
870 case IrOpcode::kDeoptimizeUnless: | 750 case IrOpcode::kDeoptimizeUnless: |
871 ProcessInput(node, 0, UseInfo::Bool()); | 751 ProcessInput(node, 0, UseInfo::Bool()); |
872 ProcessInput(node, 1, UseInfo::AnyTagged()); | 752 ProcessInput(node, 1, UseInfo::AnyTagged()); |
873 ProcessRemainingInputs(node, 2); | 753 ProcessRemainingInputs(node, 2); |
874 break; | 754 break; |
875 case IrOpcode::kBranch: | 755 case IrOpcode::kBranch: |
876 ProcessInput(node, 0, UseInfo::Bool()); | 756 ProcessInput(node, 0, UseInfo::Bool()); |
877 EnqueueInput(node, NodeProperties::FirstControlIndex(node)); | 757 EnqueueInput(node, NodeProperties::FirstControlIndex(node)); |
(...skipping 14 matching lines...) Expand all Loading... |
892 //------------------------------------------------------------------ | 772 //------------------------------------------------------------------ |
893 // For now, we assume that all JS operators were too complex to lower | 773 // For now, we assume that all JS operators were too complex to lower |
894 // to Simplified and that they will always require tagged value inputs | 774 // to Simplified and that they will always require tagged value inputs |
895 // and produce tagged value outputs. | 775 // and produce tagged value outputs. |
896 // TODO(turbofan): it might be possible to lower some JSOperators here, | 776 // TODO(turbofan): it might be possible to lower some JSOperators here, |
897 // but that responsibility really lies in the typed lowering phase. | 777 // but that responsibility really lies in the typed lowering phase. |
898 #define DEFINE_JS_CASE(x) case IrOpcode::k##x: | 778 #define DEFINE_JS_CASE(x) case IrOpcode::k##x: |
899 JS_OP_LIST(DEFINE_JS_CASE) | 779 JS_OP_LIST(DEFINE_JS_CASE) |
900 #undef DEFINE_JS_CASE | 780 #undef DEFINE_JS_CASE |
901 VisitInputs(node); | 781 VisitInputs(node); |
902 return SetOutput(node, NodeOutputInfo::AnyTagged()); | 782 return SetOutput(node, MachineRepresentation::kTagged); |
903 | 783 |
904 //------------------------------------------------------------------ | 784 //------------------------------------------------------------------ |
905 // Simplified operators. | 785 // Simplified operators. |
906 //------------------------------------------------------------------ | 786 //------------------------------------------------------------------ |
907 case IrOpcode::kBooleanNot: { | 787 case IrOpcode::kBooleanNot: { |
908 if (lower()) { | 788 if (lower()) { |
909 NodeInfo* input_info = GetInfo(node->InputAt(0)); | 789 NodeInfo* input_info = GetInfo(node->InputAt(0)); |
910 if (input_info->representation() == MachineRepresentation::kBit) { | 790 if (input_info->representation() == MachineRepresentation::kBit) { |
911 // BooleanNot(x: kRepBit) => Word32Equal(x, #0) | 791 // BooleanNot(x: kRepBit) => Word32Equal(x, #0) |
912 node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0)); | 792 node->AppendInput(jsgraph_->zone(), jsgraph_->Int32Constant(0)); |
913 NodeProperties::ChangeOp(node, lowering->machine()->Word32Equal()); | 793 NodeProperties::ChangeOp(node, lowering->machine()->Word32Equal()); |
914 } else { | 794 } else { |
915 // BooleanNot(x: kRepTagged) => WordEqual(x, #false) | 795 // BooleanNot(x: kRepTagged) => WordEqual(x, #false) |
916 node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant()); | 796 node->AppendInput(jsgraph_->zone(), jsgraph_->FalseConstant()); |
917 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); | 797 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); |
918 } | 798 } |
919 } else { | 799 } else { |
920 // No input representation requirement; adapt during lowering. | 800 // No input representation requirement; adapt during lowering. |
921 ProcessInput(node, 0, UseInfo::AnyTruncatingToBool()); | 801 ProcessInput(node, 0, UseInfo::AnyTruncatingToBool()); |
922 SetOutput(node, NodeOutputInfo::Bool()); | 802 SetOutput(node, MachineRepresentation::kBit); |
923 } | 803 } |
924 break; | 804 break; |
925 } | 805 } |
926 case IrOpcode::kBooleanToNumber: { | 806 case IrOpcode::kBooleanToNumber: { |
927 if (lower()) { | 807 if (lower()) { |
928 NodeInfo* input_info = GetInfo(node->InputAt(0)); | 808 NodeInfo* input_info = GetInfo(node->InputAt(0)); |
929 if (input_info->representation() == MachineRepresentation::kBit) { | 809 if (input_info->representation() == MachineRepresentation::kBit) { |
930 // BooleanToNumber(x: kRepBit) => x | 810 // BooleanToNumber(x: kRepBit) => x |
931 DeferReplacement(node, node->InputAt(0)); | 811 DeferReplacement(node, node->InputAt(0)); |
932 } else { | 812 } else { |
933 // BooleanToNumber(x: kRepTagged) => WordEqual(x, #true) | 813 // BooleanToNumber(x: kRepTagged) => WordEqual(x, #true) |
934 node->AppendInput(jsgraph_->zone(), jsgraph_->TrueConstant()); | 814 node->AppendInput(jsgraph_->zone(), jsgraph_->TrueConstant()); |
935 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); | 815 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); |
936 } | 816 } |
937 } else { | 817 } else { |
938 // No input representation requirement; adapt during lowering. | 818 // No input representation requirement; adapt during lowering. |
939 ProcessInput(node, 0, UseInfo::AnyTruncatingToBool()); | 819 ProcessInput(node, 0, UseInfo::AnyTruncatingToBool()); |
940 SetOutput(node, NodeOutputInfo::Int32()); | 820 SetOutput(node, MachineRepresentation::kWord32); |
941 } | 821 } |
942 break; | 822 break; |
943 } | 823 } |
944 case IrOpcode::kNumberEqual: | 824 case IrOpcode::kNumberEqual: |
945 case IrOpcode::kNumberLessThan: | 825 case IrOpcode::kNumberLessThan: |
946 case IrOpcode::kNumberLessThanOrEqual: { | 826 case IrOpcode::kNumberLessThanOrEqual: { |
947 // Number comparisons reduce to integer comparisons for integer inputs. | 827 // Number comparisons reduce to integer comparisons for integer inputs. |
948 if (BothInputsAreSigned32(node)) { | 828 if (BothInputsAreSigned32(node)) { |
949 // => signed Int32Cmp | 829 // => signed Int32Cmp |
950 VisitInt32Cmp(node); | 830 VisitInt32Cmp(node); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1058 break; | 938 break; |
1059 } | 939 } |
1060 case IrOpcode::kNumberBitwiseOr: | 940 case IrOpcode::kNumberBitwiseOr: |
1061 case IrOpcode::kNumberBitwiseXor: | 941 case IrOpcode::kNumberBitwiseXor: |
1062 case IrOpcode::kNumberBitwiseAnd: { | 942 case IrOpcode::kNumberBitwiseAnd: { |
1063 VisitInt32Binop(node); | 943 VisitInt32Binop(node); |
1064 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); | 944 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); |
1065 break; | 945 break; |
1066 } | 946 } |
1067 case IrOpcode::kNumberShiftLeft: { | 947 case IrOpcode::kNumberShiftLeft: { |
1068 Type* rhs_type = GetInfo(node->InputAt(1))->output_type(); | 948 Type* rhs_type = GetUpperBound(node->InputAt(1)); |
1069 VisitBinop(node, UseInfo::TruncatingWord32(), | 949 VisitBinop(node, UseInfo::TruncatingWord32(), |
1070 UseInfo::TruncatingWord32(), NodeOutputInfo::Int32()); | 950 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32); |
1071 if (lower()) { | 951 if (lower()) { |
1072 lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type); | 952 lowering->DoShift(node, lowering->machine()->Word32Shl(), rhs_type); |
1073 } | 953 } |
1074 break; | 954 break; |
1075 } | 955 } |
1076 case IrOpcode::kNumberShiftRight: { | 956 case IrOpcode::kNumberShiftRight: { |
1077 Type* rhs_type = GetInfo(node->InputAt(1))->output_type(); | 957 Type* rhs_type = GetUpperBound(node->InputAt(1)); |
1078 VisitBinop(node, UseInfo::TruncatingWord32(), | 958 VisitBinop(node, UseInfo::TruncatingWord32(), |
1079 UseInfo::TruncatingWord32(), NodeOutputInfo::Int32()); | 959 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32); |
1080 if (lower()) { | 960 if (lower()) { |
1081 lowering->DoShift(node, lowering->machine()->Word32Sar(), rhs_type); | 961 lowering->DoShift(node, lowering->machine()->Word32Sar(), rhs_type); |
1082 } | 962 } |
1083 break; | 963 break; |
1084 } | 964 } |
1085 case IrOpcode::kNumberShiftRightLogical: { | 965 case IrOpcode::kNumberShiftRightLogical: { |
1086 Type* rhs_type = GetInfo(node->InputAt(1))->output_type(); | 966 Type* rhs_type = GetUpperBound(node->InputAt(1)); |
1087 VisitBinop(node, UseInfo::TruncatingWord32(), | 967 VisitBinop(node, UseInfo::TruncatingWord32(), |
1088 UseInfo::TruncatingWord32(), NodeOutputInfo::Uint32()); | 968 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32); |
1089 if (lower()) { | 969 if (lower()) { |
1090 lowering->DoShift(node, lowering->machine()->Word32Shr(), rhs_type); | 970 lowering->DoShift(node, lowering->machine()->Word32Shr(), rhs_type); |
1091 } | 971 } |
1092 break; | 972 break; |
1093 } | 973 } |
1094 case IrOpcode::kNumberToInt32: { | 974 case IrOpcode::kNumberToInt32: { |
1095 // Just change representation if necessary. | 975 // Just change representation if necessary. |
1096 VisitUnop(node, UseInfo::TruncatingWord32(), NodeOutputInfo::Int32()); | 976 VisitUnop(node, UseInfo::TruncatingWord32(), |
| 977 MachineRepresentation::kWord32); |
1097 if (lower()) DeferReplacement(node, node->InputAt(0)); | 978 if (lower()) DeferReplacement(node, node->InputAt(0)); |
1098 break; | 979 break; |
1099 } | 980 } |
1100 case IrOpcode::kNumberToUint32: { | 981 case IrOpcode::kNumberToUint32: { |
1101 // Just change representation if necessary. | 982 // Just change representation if necessary. |
1102 VisitUnop(node, UseInfo::TruncatingWord32(), NodeOutputInfo::Uint32()); | 983 VisitUnop(node, UseInfo::TruncatingWord32(), |
| 984 MachineRepresentation::kWord32); |
1103 if (lower()) DeferReplacement(node, node->InputAt(0)); | 985 if (lower()) DeferReplacement(node, node->InputAt(0)); |
1104 break; | 986 break; |
1105 } | 987 } |
1106 case IrOpcode::kNumberIsHoleNaN: { | 988 case IrOpcode::kNumberIsHoleNaN: { |
1107 VisitUnop(node, UseInfo::Float64(), NodeOutputInfo::Bool()); | 989 VisitUnop(node, UseInfo::Float64(), MachineRepresentation::kBit); |
1108 if (lower()) { | 990 if (lower()) { |
1109 // NumberIsHoleNaN(x) => Word32Equal(Float64ExtractLowWord32(x), | 991 // NumberIsHoleNaN(x) => Word32Equal(Float64ExtractLowWord32(x), |
1110 // #HoleNaNLower32) | 992 // #HoleNaNLower32) |
1111 node->ReplaceInput(0, | 993 node->ReplaceInput(0, |
1112 jsgraph_->graph()->NewNode( | 994 jsgraph_->graph()->NewNode( |
1113 lowering->machine()->Float64ExtractLowWord32(), | 995 lowering->machine()->Float64ExtractLowWord32(), |
1114 node->InputAt(0))); | 996 node->InputAt(0))); |
1115 node->AppendInput(jsgraph_->zone(), | 997 node->AppendInput(jsgraph_->zone(), |
1116 jsgraph_->Int32Constant(kHoleNanLower32)); | 998 jsgraph_->Int32Constant(kHoleNanLower32)); |
1117 NodeProperties::ChangeOp(node, jsgraph_->machine()->Word32Equal()); | 999 NodeProperties::ChangeOp(node, jsgraph_->machine()->Word32Equal()); |
1118 } | 1000 } |
1119 break; | 1001 break; |
1120 } | 1002 } |
1121 case IrOpcode::kPlainPrimitiveToNumber: { | 1003 case IrOpcode::kPlainPrimitiveToNumber: { |
1122 VisitUnop(node, UseInfo::AnyTagged(), NodeOutputInfo::NumberTagged()); | 1004 VisitUnop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged); |
1123 if (lower()) { | 1005 if (lower()) { |
1124 // PlainPrimitiveToNumber(x) => Call(ToNumberStub, x, no-context) | 1006 // PlainPrimitiveToNumber(x) => Call(ToNumberStub, x, no-context) |
1125 Operator::Properties properties = node->op()->properties(); | 1007 Operator::Properties properties = node->op()->properties(); |
1126 Callable callable = CodeFactory::ToNumber(jsgraph_->isolate()); | 1008 Callable callable = CodeFactory::ToNumber(jsgraph_->isolate()); |
1127 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; | 1009 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; |
1128 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 1010 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
1129 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0, | 1011 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0, |
1130 flags, properties); | 1012 flags, properties); |
1131 node->InsertInput(jsgraph_->zone(), 0, | 1013 node->InsertInput(jsgraph_->zone(), 0, |
1132 jsgraph_->HeapConstant(callable.code())); | 1014 jsgraph_->HeapConstant(callable.code())); |
1133 node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant()); | 1015 node->AppendInput(jsgraph_->zone(), jsgraph_->NoContextConstant()); |
1134 NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc)); | 1016 NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc)); |
1135 } | 1017 } |
1136 break; | 1018 break; |
1137 } | 1019 } |
1138 case IrOpcode::kReferenceEqual: { | 1020 case IrOpcode::kReferenceEqual: { |
1139 VisitBinop(node, UseInfo::AnyTagged(), NodeOutputInfo::Bool()); | 1021 VisitBinop(node, UseInfo::AnyTagged(), MachineRepresentation::kBit); |
1140 if (lower()) { | 1022 if (lower()) { |
1141 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); | 1023 NodeProperties::ChangeOp(node, lowering->machine()->WordEqual()); |
1142 } | 1024 } |
1143 break; | 1025 break; |
1144 } | 1026 } |
1145 case IrOpcode::kStringEqual: { | 1027 case IrOpcode::kStringEqual: { |
1146 VisitBinop(node, UseInfo::AnyTagged(), NodeOutputInfo::BoolTagged()); | 1028 VisitBinop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged); |
1147 if (lower()) { | 1029 if (lower()) { |
1148 // StringEqual(x, y) => Call(StringEqualStub, x, y, no-context) | 1030 // StringEqual(x, y) => Call(StringEqualStub, x, y, no-context) |
1149 Operator::Properties properties = node->op()->properties(); | 1031 Operator::Properties properties = node->op()->properties(); |
1150 Callable callable = CodeFactory::StringEqual(jsgraph_->isolate()); | 1032 Callable callable = CodeFactory::StringEqual(jsgraph_->isolate()); |
1151 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; | 1033 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; |
1152 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 1034 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
1153 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0, | 1035 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0, |
1154 flags, properties); | 1036 flags, properties); |
1155 node->InsertInput(jsgraph_->zone(), 0, | 1037 node->InsertInput(jsgraph_->zone(), 0, |
1156 jsgraph_->HeapConstant(callable.code())); | 1038 jsgraph_->HeapConstant(callable.code())); |
1157 node->InsertInput(jsgraph_->zone(), 3, jsgraph_->NoContextConstant()); | 1039 node->InsertInput(jsgraph_->zone(), 3, jsgraph_->NoContextConstant()); |
1158 NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc)); | 1040 NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc)); |
1159 } | 1041 } |
1160 break; | 1042 break; |
1161 } | 1043 } |
1162 case IrOpcode::kStringLessThan: { | 1044 case IrOpcode::kStringLessThan: { |
1163 VisitBinop(node, UseInfo::AnyTagged(), NodeOutputInfo::BoolTagged()); | 1045 VisitBinop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged); |
1164 if (lower()) { | 1046 if (lower()) { |
1165 // StringLessThan(x, y) => Call(StringLessThanStub, x, y, no-context) | 1047 // StringLessThan(x, y) => Call(StringLessThanStub, x, y, no-context) |
1166 Operator::Properties properties = node->op()->properties(); | 1048 Operator::Properties properties = node->op()->properties(); |
1167 Callable callable = CodeFactory::StringLessThan(jsgraph_->isolate()); | 1049 Callable callable = CodeFactory::StringLessThan(jsgraph_->isolate()); |
1168 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; | 1050 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; |
1169 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 1051 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
1170 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0, | 1052 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0, |
1171 flags, properties); | 1053 flags, properties); |
1172 node->InsertInput(jsgraph_->zone(), 0, | 1054 node->InsertInput(jsgraph_->zone(), 0, |
1173 jsgraph_->HeapConstant(callable.code())); | 1055 jsgraph_->HeapConstant(callable.code())); |
1174 node->InsertInput(jsgraph_->zone(), 3, jsgraph_->NoContextConstant()); | 1056 node->InsertInput(jsgraph_->zone(), 3, jsgraph_->NoContextConstant()); |
1175 NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc)); | 1057 NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc)); |
1176 } | 1058 } |
1177 break; | 1059 break; |
1178 } | 1060 } |
1179 case IrOpcode::kStringLessThanOrEqual: { | 1061 case IrOpcode::kStringLessThanOrEqual: { |
1180 VisitBinop(node, UseInfo::AnyTagged(), NodeOutputInfo::BoolTagged()); | 1062 VisitBinop(node, UseInfo::AnyTagged(), MachineRepresentation::kTagged); |
1181 if (lower()) { | 1063 if (lower()) { |
1182 // StringLessThanOrEqual(x, y) | 1064 // StringLessThanOrEqual(x, y) |
1183 // => Call(StringLessThanOrEqualStub, x, y, no-context) | 1065 // => Call(StringLessThanOrEqualStub, x, y, no-context) |
1184 Operator::Properties properties = node->op()->properties(); | 1066 Operator::Properties properties = node->op()->properties(); |
1185 Callable callable = | 1067 Callable callable = |
1186 CodeFactory::StringLessThanOrEqual(jsgraph_->isolate()); | 1068 CodeFactory::StringLessThanOrEqual(jsgraph_->isolate()); |
1187 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; | 1069 CallDescriptor::Flags flags = CallDescriptor::kNoFlags; |
1188 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 1070 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
1189 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0, | 1071 jsgraph_->isolate(), jsgraph_->zone(), callable.descriptor(), 0, |
1190 flags, properties); | 1072 flags, properties); |
1191 node->InsertInput(jsgraph_->zone(), 0, | 1073 node->InsertInput(jsgraph_->zone(), 0, |
1192 jsgraph_->HeapConstant(callable.code())); | 1074 jsgraph_->HeapConstant(callable.code())); |
1193 node->InsertInput(jsgraph_->zone(), 3, jsgraph_->NoContextConstant()); | 1075 node->InsertInput(jsgraph_->zone(), 3, jsgraph_->NoContextConstant()); |
1194 NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc)); | 1076 NodeProperties::ChangeOp(node, jsgraph_->common()->Call(desc)); |
1195 } | 1077 } |
1196 break; | 1078 break; |
1197 } | 1079 } |
1198 case IrOpcode::kAllocate: { | 1080 case IrOpcode::kAllocate: { |
1199 ProcessInput(node, 0, UseInfo::AnyTagged()); | 1081 ProcessInput(node, 0, UseInfo::AnyTagged()); |
1200 ProcessRemainingInputs(node, 1); | 1082 ProcessRemainingInputs(node, 1); |
1201 SetOutput(node, NodeOutputInfo::AnyTagged()); | 1083 SetOutput(node, MachineRepresentation::kTagged); |
1202 break; | 1084 break; |
1203 } | 1085 } |
1204 case IrOpcode::kLoadField: { | 1086 case IrOpcode::kLoadField: { |
1205 FieldAccess access = FieldAccessOf(node->op()); | 1087 FieldAccess access = FieldAccessOf(node->op()); |
1206 ProcessInput(node, 0, UseInfoForBasePointer(access)); | 1088 ProcessInput(node, 0, UseInfoForBasePointer(access)); |
1207 ProcessRemainingInputs(node, 1); | 1089 ProcessRemainingInputs(node, 1); |
1208 SetOutputFromMachineType(node, access.machine_type); | 1090 SetOutput(node, access.machine_type.representation()); |
1209 break; | 1091 break; |
1210 } | 1092 } |
1211 case IrOpcode::kStoreField: { | 1093 case IrOpcode::kStoreField: { |
1212 FieldAccess access = FieldAccessOf(node->op()); | 1094 FieldAccess access = FieldAccessOf(node->op()); |
1213 ProcessInput(node, 0, UseInfoForBasePointer(access)); | 1095 ProcessInput(node, 0, UseInfoForBasePointer(access)); |
1214 ProcessInput(node, 1, TruncatingUseInfoFromRepresentation( | 1096 ProcessInput(node, 1, TruncatingUseInfoFromRepresentation( |
1215 access.machine_type.representation())); | 1097 access.machine_type.representation())); |
1216 ProcessRemainingInputs(node, 2); | 1098 ProcessRemainingInputs(node, 2); |
1217 SetOutput(node, NodeOutputInfo::None()); | 1099 SetOutput(node, MachineRepresentation::kNone); |
1218 break; | 1100 break; |
1219 } | 1101 } |
1220 case IrOpcode::kLoadBuffer: { | 1102 case IrOpcode::kLoadBuffer: { |
1221 BufferAccess access = BufferAccessOf(node->op()); | 1103 BufferAccess access = BufferAccessOf(node->op()); |
1222 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer | 1104 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer |
1223 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset | 1105 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset |
1224 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length | 1106 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length |
1225 ProcessRemainingInputs(node, 3); | 1107 ProcessRemainingInputs(node, 3); |
1226 | 1108 |
1227 NodeOutputInfo output_info; | 1109 MachineRepresentation output; |
1228 if (truncation.TruncatesUndefinedToZeroOrNaN()) { | 1110 if (truncation.TruncatesUndefinedToZeroOrNaN()) { |
1229 if (truncation.TruncatesNaNToZero()) { | 1111 if (truncation.TruncatesNaNToZero()) { |
1230 // If undefined is truncated to a non-NaN number, we can use | 1112 // If undefined is truncated to a non-NaN number, we can use |
1231 // the load's representation. | 1113 // the load's representation. |
1232 output_info = NodeOutputInfo(access.machine_type().representation(), | 1114 output = access.machine_type().representation(); |
1233 NodeProperties::GetType(node)); | |
1234 } else { | 1115 } else { |
1235 // If undefined is truncated to a number, but the use can | 1116 // If undefined is truncated to a number, but the use can |
1236 // observe NaN, we need to output at least the float32 | 1117 // observe NaN, we need to output at least the float32 |
1237 // representation. | 1118 // representation. |
1238 if (access.machine_type().representation() == | 1119 if (access.machine_type().representation() == |
1239 MachineRepresentation::kFloat32) { | 1120 MachineRepresentation::kFloat32) { |
1240 output_info = | 1121 output = access.machine_type().representation(); |
1241 NodeOutputInfo(access.machine_type().representation(), | |
1242 NodeProperties::GetType(node)); | |
1243 } else { | 1122 } else { |
1244 if (access.machine_type().representation() != | 1123 if (access.machine_type().representation() != |
1245 MachineRepresentation::kFloat64) { | 1124 MachineRepresentation::kFloat64) { |
1246 // TODO(bmeurer): See comment on abort_compilation_. | 1125 // TODO(bmeurer): See comment on abort_compilation_. |
1247 if (lower()) lowering->abort_compilation_ = true; | 1126 if (lower()) lowering->abort_compilation_ = true; |
1248 } | 1127 } |
1249 output_info = NodeOutputInfo::Float64(); | 1128 output = MachineRepresentation::kFloat64; |
1250 } | 1129 } |
1251 } | 1130 } |
1252 } else { | 1131 } else { |
1253 // TODO(bmeurer): See comment on abort_compilation_. | 1132 // TODO(bmeurer): See comment on abort_compilation_. |
1254 if (lower()) lowering->abort_compilation_ = true; | 1133 if (lower()) lowering->abort_compilation_ = true; |
1255 | 1134 |
1256 // If undefined is not truncated away, we need to have the tagged | 1135 // If undefined is not truncated away, we need to have the tagged |
1257 // representation. | 1136 // representation. |
1258 output_info = NodeOutputInfo::AnyTagged(); | 1137 output = MachineRepresentation::kTagged; |
1259 } | 1138 } |
1260 SetOutput(node, output_info); | 1139 SetOutput(node, output); |
1261 if (lower()) | 1140 if (lower()) lowering->DoLoadBuffer(node, output, changer_); |
1262 lowering->DoLoadBuffer(node, output_info.representation(), changer_); | |
1263 break; | 1141 break; |
1264 } | 1142 } |
1265 case IrOpcode::kStoreBuffer: { | 1143 case IrOpcode::kStoreBuffer: { |
1266 BufferAccess access = BufferAccessOf(node->op()); | 1144 BufferAccess access = BufferAccessOf(node->op()); |
1267 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer | 1145 ProcessInput(node, 0, UseInfo::PointerInt()); // buffer |
1268 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset | 1146 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // offset |
1269 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length | 1147 ProcessInput(node, 2, UseInfo::TruncatingWord32()); // length |
1270 ProcessInput(node, 3, | 1148 ProcessInput(node, 3, |
1271 TruncatingUseInfoFromRepresentation( | 1149 TruncatingUseInfoFromRepresentation( |
1272 access.machine_type().representation())); // value | 1150 access.machine_type().representation())); // value |
1273 ProcessRemainingInputs(node, 4); | 1151 ProcessRemainingInputs(node, 4); |
1274 SetOutput(node, NodeOutputInfo::None()); | 1152 SetOutput(node, MachineRepresentation::kNone); |
1275 if (lower()) lowering->DoStoreBuffer(node); | 1153 if (lower()) lowering->DoStoreBuffer(node); |
1276 break; | 1154 break; |
1277 } | 1155 } |
1278 case IrOpcode::kLoadElement: { | 1156 case IrOpcode::kLoadElement: { |
1279 ElementAccess access = ElementAccessOf(node->op()); | 1157 ElementAccess access = ElementAccessOf(node->op()); |
1280 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base | 1158 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base |
1281 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index | 1159 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index |
1282 ProcessRemainingInputs(node, 2); | 1160 ProcessRemainingInputs(node, 2); |
1283 SetOutputFromMachineType(node, access.machine_type); | 1161 SetOutput(node, access.machine_type.representation()); |
1284 break; | 1162 break; |
1285 } | 1163 } |
1286 case IrOpcode::kStoreElement: { | 1164 case IrOpcode::kStoreElement: { |
1287 ElementAccess access = ElementAccessOf(node->op()); | 1165 ElementAccess access = ElementAccessOf(node->op()); |
1288 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base | 1166 ProcessInput(node, 0, UseInfoForBasePointer(access)); // base |
1289 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index | 1167 ProcessInput(node, 1, UseInfo::TruncatingWord32()); // index |
1290 ProcessInput(node, 2, | 1168 ProcessInput(node, 2, |
1291 TruncatingUseInfoFromRepresentation( | 1169 TruncatingUseInfoFromRepresentation( |
1292 access.machine_type.representation())); // value | 1170 access.machine_type.representation())); // value |
1293 ProcessRemainingInputs(node, 3); | 1171 ProcessRemainingInputs(node, 3); |
1294 SetOutput(node, NodeOutputInfo::None()); | 1172 SetOutput(node, MachineRepresentation::kNone); |
1295 break; | 1173 break; |
1296 } | 1174 } |
1297 case IrOpcode::kObjectIsNumber: | 1175 case IrOpcode::kObjectIsNumber: |
1298 case IrOpcode::kObjectIsReceiver: | 1176 case IrOpcode::kObjectIsReceiver: |
1299 case IrOpcode::kObjectIsSmi: | 1177 case IrOpcode::kObjectIsSmi: |
1300 case IrOpcode::kObjectIsUndetectable: { | 1178 case IrOpcode::kObjectIsUndetectable: { |
1301 ProcessInput(node, 0, UseInfo::AnyTagged()); | 1179 ProcessInput(node, 0, UseInfo::AnyTagged()); |
1302 SetOutput(node, NodeOutputInfo::Bool()); | 1180 SetOutput(node, MachineRepresentation::kBit); |
1303 break; | 1181 break; |
1304 } | 1182 } |
1305 | 1183 |
1306 //------------------------------------------------------------------ | 1184 //------------------------------------------------------------------ |
1307 // Machine-level operators. | 1185 // Machine-level operators. |
1308 //------------------------------------------------------------------ | 1186 //------------------------------------------------------------------ |
1309 case IrOpcode::kLoad: { | 1187 case IrOpcode::kLoad: { |
1310 // TODO(jarin) Eventually, we should get rid of all machine stores | 1188 // TODO(jarin) Eventually, we should get rid of all machine stores |
1311 // from the high-level phases, then this becomes UNREACHABLE. | 1189 // from the high-level phases, then this becomes UNREACHABLE. |
1312 LoadRepresentation rep = LoadRepresentationOf(node->op()); | 1190 LoadRepresentation rep = LoadRepresentationOf(node->op()); |
1313 ProcessInput(node, 0, UseInfo::AnyTagged()); // tagged pointer | 1191 ProcessInput(node, 0, UseInfo::AnyTagged()); // tagged pointer |
1314 ProcessInput(node, 1, UseInfo::PointerInt()); // index | 1192 ProcessInput(node, 1, UseInfo::PointerInt()); // index |
1315 ProcessRemainingInputs(node, 2); | 1193 ProcessRemainingInputs(node, 2); |
1316 SetOutputFromMachineType(node, rep); | 1194 SetOutput(node, rep.representation()); |
1317 break; | 1195 break; |
1318 } | 1196 } |
1319 case IrOpcode::kStore: { | 1197 case IrOpcode::kStore: { |
1320 // TODO(jarin) Eventually, we should get rid of all machine stores | 1198 // TODO(jarin) Eventually, we should get rid of all machine stores |
1321 // from the high-level phases, then this becomes UNREACHABLE. | 1199 // from the high-level phases, then this becomes UNREACHABLE. |
1322 StoreRepresentation rep = StoreRepresentationOf(node->op()); | 1200 StoreRepresentation rep = StoreRepresentationOf(node->op()); |
1323 ProcessInput(node, 0, UseInfo::AnyTagged()); // tagged pointer | 1201 ProcessInput(node, 0, UseInfo::AnyTagged()); // tagged pointer |
1324 ProcessInput(node, 1, UseInfo::PointerInt()); // index | 1202 ProcessInput(node, 1, UseInfo::PointerInt()); // index |
1325 ProcessInput(node, 2, | 1203 ProcessInput(node, 2, |
1326 TruncatingUseInfoFromRepresentation(rep.representation())); | 1204 TruncatingUseInfoFromRepresentation(rep.representation())); |
1327 ProcessRemainingInputs(node, 3); | 1205 ProcessRemainingInputs(node, 3); |
1328 SetOutput(node, NodeOutputInfo::None()); | 1206 SetOutput(node, MachineRepresentation::kNone); |
1329 break; | 1207 break; |
1330 } | 1208 } |
1331 case IrOpcode::kWord32Shr: | 1209 case IrOpcode::kWord32Shr: |
1332 // We output unsigned int32 for shift right because JavaScript. | 1210 // We output unsigned int32 for shift right because JavaScript. |
1333 return VisitBinop(node, UseInfo::TruncatingWord32(), | 1211 return VisitBinop(node, UseInfo::TruncatingWord32(), |
1334 NodeOutputInfo::Uint32()); | 1212 MachineRepresentation::kWord32); |
1335 case IrOpcode::kWord32And: | 1213 case IrOpcode::kWord32And: |
1336 case IrOpcode::kWord32Or: | 1214 case IrOpcode::kWord32Or: |
1337 case IrOpcode::kWord32Xor: | 1215 case IrOpcode::kWord32Xor: |
1338 case IrOpcode::kWord32Shl: | 1216 case IrOpcode::kWord32Shl: |
1339 case IrOpcode::kWord32Sar: | 1217 case IrOpcode::kWord32Sar: |
1340 // We use signed int32 as the output type for these word32 operations, | 1218 // We use signed int32 as the output type for these word32 operations, |
1341 // though the machine bits are the same for either signed or unsigned, | 1219 // though the machine bits are the same for either signed or unsigned, |
1342 // because JavaScript considers the result from these operations signed. | 1220 // because JavaScript considers the result from these operations signed. |
1343 return VisitBinop(node, UseInfo::TruncatingWord32(), | 1221 return VisitBinop(node, UseInfo::TruncatingWord32(), |
1344 NodeOutputInfo::Int32()); | 1222 MachineRepresentation::kWord32); |
1345 case IrOpcode::kWord32Equal: | 1223 case IrOpcode::kWord32Equal: |
1346 return VisitBinop(node, UseInfo::TruncatingWord32(), | 1224 return VisitBinop(node, UseInfo::TruncatingWord32(), |
1347 NodeOutputInfo::Bool()); | 1225 MachineRepresentation::kBit); |
1348 | 1226 |
1349 case IrOpcode::kWord32Clz: | 1227 case IrOpcode::kWord32Clz: |
1350 return VisitUnop(node, UseInfo::TruncatingWord32(), | 1228 return VisitUnop(node, UseInfo::TruncatingWord32(), |
1351 NodeOutputInfo::Uint32()); | 1229 MachineRepresentation::kWord32); |
1352 | 1230 |
1353 case IrOpcode::kInt32Add: | 1231 case IrOpcode::kInt32Add: |
1354 case IrOpcode::kInt32Sub: | 1232 case IrOpcode::kInt32Sub: |
1355 case IrOpcode::kInt32Mul: | 1233 case IrOpcode::kInt32Mul: |
1356 case IrOpcode::kInt32MulHigh: | 1234 case IrOpcode::kInt32MulHigh: |
1357 case IrOpcode::kInt32Div: | 1235 case IrOpcode::kInt32Div: |
1358 case IrOpcode::kInt32Mod: | 1236 case IrOpcode::kInt32Mod: |
1359 return VisitInt32Binop(node); | 1237 return VisitInt32Binop(node); |
1360 case IrOpcode::kUint32Div: | 1238 case IrOpcode::kUint32Div: |
1361 case IrOpcode::kUint32Mod: | 1239 case IrOpcode::kUint32Mod: |
(...skipping 24 matching lines...) Expand all Loading... |
1386 case IrOpcode::kUint64Mod: | 1264 case IrOpcode::kUint64Mod: |
1387 return VisitUint64Binop(node); | 1265 return VisitUint64Binop(node); |
1388 | 1266 |
1389 case IrOpcode::kWord64And: | 1267 case IrOpcode::kWord64And: |
1390 case IrOpcode::kWord64Or: | 1268 case IrOpcode::kWord64Or: |
1391 case IrOpcode::kWord64Xor: | 1269 case IrOpcode::kWord64Xor: |
1392 case IrOpcode::kWord64Shl: | 1270 case IrOpcode::kWord64Shl: |
1393 case IrOpcode::kWord64Shr: | 1271 case IrOpcode::kWord64Shr: |
1394 case IrOpcode::kWord64Sar: | 1272 case IrOpcode::kWord64Sar: |
1395 return VisitBinop(node, UseInfo::TruncatingWord64(), | 1273 return VisitBinop(node, UseInfo::TruncatingWord64(), |
1396 NodeOutputInfo::Int64()); | 1274 MachineRepresentation::kWord64); |
1397 case IrOpcode::kWord64Equal: | 1275 case IrOpcode::kWord64Equal: |
1398 return VisitBinop(node, UseInfo::TruncatingWord64(), | 1276 return VisitBinop(node, UseInfo::TruncatingWord64(), |
1399 NodeOutputInfo::Bool()); | 1277 MachineRepresentation::kBit); |
1400 | 1278 |
1401 case IrOpcode::kChangeInt32ToInt64: | 1279 case IrOpcode::kChangeInt32ToInt64: |
1402 return VisitUnop( | 1280 return VisitUnop(node, UseInfo::TruncatingWord32(), |
1403 node, UseInfo::TruncatingWord32(), | 1281 MachineRepresentation::kWord64); |
1404 NodeOutputInfo(MachineRepresentation::kWord64, Type::Signed32())); | |
1405 case IrOpcode::kChangeUint32ToUint64: | 1282 case IrOpcode::kChangeUint32ToUint64: |
1406 return VisitUnop( | 1283 return VisitUnop(node, UseInfo::TruncatingWord32(), |
1407 node, UseInfo::TruncatingWord32(), | 1284 MachineRepresentation::kWord64); |
1408 NodeOutputInfo(MachineRepresentation::kWord64, Type::Unsigned32())); | |
1409 case IrOpcode::kTruncateFloat64ToFloat32: | 1285 case IrOpcode::kTruncateFloat64ToFloat32: |
1410 return VisitUnop(node, UseInfo::Float64(), NodeOutputInfo::Float32()); | 1286 return VisitUnop(node, UseInfo::Float64(), |
| 1287 MachineRepresentation::kFloat32); |
1411 case IrOpcode::kTruncateFloat64ToInt32: | 1288 case IrOpcode::kTruncateFloat64ToInt32: |
1412 return VisitUnop(node, UseInfo::Float64(), NodeOutputInfo::Int32()); | 1289 return VisitUnop(node, UseInfo::Float64(), |
| 1290 MachineRepresentation::kWord32); |
1413 case IrOpcode::kTruncateInt64ToInt32: | 1291 case IrOpcode::kTruncateInt64ToInt32: |
1414 // TODO(titzer): Is kTypeInt32 correct here? | 1292 // TODO(titzer): Is kTypeInt32 correct here? |
1415 return VisitUnop(node, UseInfo::Word64TruncatingToWord32(), | 1293 return VisitUnop(node, UseInfo::Word64TruncatingToWord32(), |
1416 NodeOutputInfo::Int32()); | 1294 MachineRepresentation::kWord32); |
1417 | 1295 |
1418 case IrOpcode::kChangeFloat32ToFloat64: | 1296 case IrOpcode::kChangeFloat32ToFloat64: |
1419 return VisitUnop(node, UseInfo::Float32(), NodeOutputInfo::Float64()); | 1297 return VisitUnop(node, UseInfo::Float32(), |
| 1298 MachineRepresentation::kFloat64); |
1420 case IrOpcode::kChangeInt32ToFloat64: | 1299 case IrOpcode::kChangeInt32ToFloat64: |
1421 return VisitUnop( | 1300 return VisitUnop(node, UseInfo::TruncatingWord32(), |
1422 node, UseInfo::TruncatingWord32(), | 1301 MachineRepresentation::kFloat64); |
1423 NodeOutputInfo(MachineRepresentation::kFloat64, Type::Signed32())); | |
1424 case IrOpcode::kChangeUint32ToFloat64: | 1302 case IrOpcode::kChangeUint32ToFloat64: |
1425 return VisitUnop(node, UseInfo::TruncatingWord32(), | 1303 return VisitUnop(node, UseInfo::TruncatingWord32(), |
1426 NodeOutputInfo(MachineRepresentation::kFloat64, | 1304 MachineRepresentation::kFloat64); |
1427 Type::Unsigned32())); | |
1428 case IrOpcode::kChangeFloat64ToInt32: | 1305 case IrOpcode::kChangeFloat64ToInt32: |
1429 return VisitUnop(node, UseInfo::Float64TruncatingToWord32(), | 1306 return VisitUnop(node, UseInfo::Float64TruncatingToWord32(), |
1430 NodeOutputInfo::Int32()); | 1307 MachineRepresentation::kWord32); |
1431 case IrOpcode::kChangeFloat64ToUint32: | 1308 case IrOpcode::kChangeFloat64ToUint32: |
1432 return VisitUnop(node, UseInfo::Float64TruncatingToWord32(), | 1309 return VisitUnop(node, UseInfo::Float64TruncatingToWord32(), |
1433 NodeOutputInfo::Uint32()); | 1310 MachineRepresentation::kWord32); |
1434 | 1311 |
1435 case IrOpcode::kFloat64Add: | 1312 case IrOpcode::kFloat64Add: |
1436 case IrOpcode::kFloat64Sub: | 1313 case IrOpcode::kFloat64Sub: |
1437 case IrOpcode::kFloat64Mul: | 1314 case IrOpcode::kFloat64Mul: |
1438 case IrOpcode::kFloat64Div: | 1315 case IrOpcode::kFloat64Div: |
1439 case IrOpcode::kFloat64Mod: | 1316 case IrOpcode::kFloat64Mod: |
1440 case IrOpcode::kFloat64Min: | 1317 case IrOpcode::kFloat64Min: |
1441 return VisitFloat64Binop(node); | 1318 return VisitFloat64Binop(node); |
1442 case IrOpcode::kFloat64Abs: | 1319 case IrOpcode::kFloat64Abs: |
1443 case IrOpcode::kFloat64Sqrt: | 1320 case IrOpcode::kFloat64Sqrt: |
1444 case IrOpcode::kFloat64RoundDown: | 1321 case IrOpcode::kFloat64RoundDown: |
1445 case IrOpcode::kFloat64RoundTruncate: | 1322 case IrOpcode::kFloat64RoundTruncate: |
1446 case IrOpcode::kFloat64RoundTiesAway: | 1323 case IrOpcode::kFloat64RoundTiesAway: |
1447 case IrOpcode::kFloat64RoundUp: | 1324 case IrOpcode::kFloat64RoundUp: |
1448 return VisitUnop(node, UseInfo::Float64(), NodeOutputInfo::Float64()); | 1325 return VisitUnop(node, UseInfo::Float64(), |
| 1326 MachineRepresentation::kFloat64); |
1449 case IrOpcode::kFloat64Equal: | 1327 case IrOpcode::kFloat64Equal: |
1450 case IrOpcode::kFloat64LessThan: | 1328 case IrOpcode::kFloat64LessThan: |
1451 case IrOpcode::kFloat64LessThanOrEqual: | 1329 case IrOpcode::kFloat64LessThanOrEqual: |
1452 return VisitFloat64Cmp(node); | 1330 return VisitFloat64Cmp(node); |
1453 case IrOpcode::kFloat64ExtractLowWord32: | 1331 case IrOpcode::kFloat64ExtractLowWord32: |
1454 case IrOpcode::kFloat64ExtractHighWord32: | 1332 case IrOpcode::kFloat64ExtractHighWord32: |
1455 return VisitUnop(node, UseInfo::Float64(), NodeOutputInfo::Int32()); | 1333 return VisitUnop(node, UseInfo::Float64(), |
| 1334 MachineRepresentation::kWord32); |
1456 case IrOpcode::kFloat64InsertLowWord32: | 1335 case IrOpcode::kFloat64InsertLowWord32: |
1457 case IrOpcode::kFloat64InsertHighWord32: | 1336 case IrOpcode::kFloat64InsertHighWord32: |
1458 return VisitBinop(node, UseInfo::Float64(), UseInfo::TruncatingWord32(), | 1337 return VisitBinop(node, UseInfo::Float64(), UseInfo::TruncatingWord32(), |
1459 NodeOutputInfo::Float64()); | 1338 MachineRepresentation::kFloat64); |
1460 case IrOpcode::kLoadStackPointer: | 1339 case IrOpcode::kLoadStackPointer: |
1461 case IrOpcode::kLoadFramePointer: | 1340 case IrOpcode::kLoadFramePointer: |
1462 case IrOpcode::kLoadParentFramePointer: | 1341 case IrOpcode::kLoadParentFramePointer: |
1463 return VisitLeaf(node, NodeOutputInfo::Pointer()); | 1342 return VisitLeaf(node, MachineType::PointerRepresentation()); |
1464 case IrOpcode::kStateValues: | 1343 case IrOpcode::kStateValues: |
1465 VisitStateValues(node); | 1344 VisitStateValues(node); |
1466 break; | 1345 break; |
1467 default: | 1346 default: |
1468 VisitInputs(node); | 1347 VisitInputs(node); |
1469 // Assume the output is tagged. | 1348 // Assume the output is tagged. |
1470 SetOutput(node, NodeOutputInfo::AnyTagged()); | 1349 SetOutput(node, MachineRepresentation::kTagged); |
1471 break; | 1350 break; |
1472 } | 1351 } |
1473 } | 1352 } |
1474 | 1353 |
1475 void DeferReplacement(Node* node, Node* replacement) { | 1354 void DeferReplacement(Node* node, Node* replacement) { |
1476 TRACE("defer replacement #%d:%s with #%d:%s\n", node->id(), | 1355 TRACE("defer replacement #%d:%s with #%d:%s\n", node->id(), |
1477 node->op()->mnemonic(), replacement->id(), | 1356 node->op()->mnemonic(), replacement->id(), |
1478 replacement->op()->mnemonic()); | 1357 replacement->op()->mnemonic()); |
1479 | 1358 |
1480 if (replacement->id() < count_ && | 1359 if (replacement->id() < count_ && |
1481 GetInfo(node)->output_type()->Is(GetInfo(replacement)->output_type())) { | 1360 GetUpperBound(node)->Is(GetUpperBound(replacement))) { |
1482 // Replace with a previously existing node eagerly only if the type is the | 1361 // Replace with a previously existing node eagerly only if the type is the |
1483 // same. | 1362 // same. |
1484 node->ReplaceUses(replacement); | 1363 node->ReplaceUses(replacement); |
1485 } else { | 1364 } else { |
1486 // Otherwise, we are replacing a node with a representation change. | 1365 // Otherwise, we are replacing a node with a representation change. |
1487 // Such a substitution must be done after all lowering is done, because | 1366 // Such a substitution must be done after all lowering is done, because |
1488 // changing the type could confuse the representation change | 1367 // changing the type could confuse the representation change |
1489 // insertion for uses of the node. | 1368 // insertion for uses of the node. |
1490 replacements_.push_back(node); | 1369 replacements_.push_back(node); |
1491 replacements_.push_back(replacement); | 1370 replacements_.push_back(replacement); |
1492 } | 1371 } |
1493 node->NullAllInputs(); // Node is now dead. | 1372 node->NullAllInputs(); // Node is now dead. |
1494 } | 1373 } |
1495 | 1374 |
1496 void PrintOutputInfo(NodeInfo* info) { | 1375 void PrintOutputInfo(NodeInfo* info) { |
1497 if (FLAG_trace_representation) { | 1376 if (FLAG_trace_representation) { |
1498 OFStream os(stdout); | 1377 OFStream os(stdout); |
1499 os << info->representation() << " ("; | 1378 os << info->representation(); |
1500 info->output_type()->PrintTo(os, Type::SEMANTIC_DIM); | |
1501 os << ")"; | |
1502 } | 1379 } |
1503 } | 1380 } |
1504 | 1381 |
1505 void PrintRepresentation(MachineRepresentation rep) { | 1382 void PrintRepresentation(MachineRepresentation rep) { |
1506 if (FLAG_trace_representation) { | 1383 if (FLAG_trace_representation) { |
1507 OFStream os(stdout); | 1384 OFStream os(stdout); |
1508 os << rep; | 1385 os << rep; |
1509 } | 1386 } |
1510 } | 1387 } |
1511 | 1388 |
(...skipping 382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1894 if (!rhs_type->Is(type_cache_.kZeroToThirtyOne)) { | 1771 if (!rhs_type->Is(type_cache_.kZeroToThirtyOne)) { |
1895 node->ReplaceInput(1, graph()->NewNode(machine()->Word32And(), rhs, | 1772 node->ReplaceInput(1, graph()->NewNode(machine()->Word32And(), rhs, |
1896 jsgraph()->Int32Constant(0x1f))); | 1773 jsgraph()->Int32Constant(0x1f))); |
1897 } | 1774 } |
1898 NodeProperties::ChangeOp(node, op); | 1775 NodeProperties::ChangeOp(node, op); |
1899 } | 1776 } |
1900 | 1777 |
1901 } // namespace compiler | 1778 } // namespace compiler |
1902 } // namespace internal | 1779 } // namespace internal |
1903 } // namespace v8 | 1780 } // namespace v8 |
OLD | NEW |