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 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 const Operator* Uint32Op(Node* node) { | 467 const Operator* Uint32Op(Node* node) { |
468 return changer_->Uint32OperatorFor(node->opcode()); | 468 return changer_->Uint32OperatorFor(node->opcode()); |
469 } | 469 } |
470 | 470 |
471 const Operator* Float64Op(Node* node) { | 471 const Operator* Float64Op(Node* node) { |
472 return changer_->Float64OperatorFor(node->opcode()); | 472 return changer_->Float64OperatorFor(node->opcode()); |
473 } | 473 } |
474 | 474 |
475 bool CanLowerToInt32Binop(Node* node, MachineTypeUnion use) { | 475 bool CanLowerToInt32Binop(Node* node, MachineTypeUnion use) { |
476 return BothInputsAre(node, Type::Signed32()) && | 476 return BothInputsAre(node, Type::Signed32()) && |
477 (!CanObserveNonInt32(use) || | 477 (!CanObserveNonWord32(use) || |
478 NodeProperties::GetType(node)->Is(Type::Signed32())); | 478 NodeProperties::GetType(node)->Is(Type::Signed32())); |
479 } | 479 } |
480 | 480 |
481 bool CanLowerToInt32AdditiveBinop(Node* node, MachineTypeUnion use) { | 481 bool CanLowerToWord32AdditiveBinop(Node* node, MachineTypeUnion use) { |
482 return BothInputsAre(node, safe_int_additive_range_) && | 482 return BothInputsAre(node, safe_int_additive_range_) && |
483 !CanObserveNonInt32(use); | 483 !CanObserveNonWord32(use); |
484 } | 484 } |
485 | 485 |
486 bool CanLowerToUint32Binop(Node* node, MachineTypeUnion use) { | 486 bool CanLowerToUint32Binop(Node* node, MachineTypeUnion use) { |
487 return BothInputsAre(node, Type::Unsigned32()) && | 487 return BothInputsAre(node, Type::Unsigned32()) && |
488 (!CanObserveNonUint32(use) || | 488 (!CanObserveNonWord32(use) || |
489 NodeProperties::GetType(node)->Is(Type::Unsigned32())); | 489 NodeProperties::GetType(node)->Is(Type::Unsigned32())); |
490 } | 490 } |
491 | 491 |
492 bool CanLowerToUint32AdditiveBinop(Node* node, MachineTypeUnion use) { | |
493 return BothInputsAre(node, safe_int_additive_range_) && | |
494 !CanObserveNonUint32(use); | |
495 } | |
496 | |
497 bool CanObserveNonWord32(MachineTypeUnion use) { | 492 bool CanObserveNonWord32(MachineTypeUnion use) { |
498 return (use & ~(kTypeUint32 | kTypeInt32)) != 0; | 493 return (use & kTypeMask & ~(kTypeInt32 | kTypeUint32)) != 0; |
499 } | |
500 | |
501 bool CanObserveNonInt32(MachineTypeUnion use) { | |
502 return (use & (kTypeUint32 | kTypeNumber | kTypeAny)) != 0; | |
503 } | 494 } |
504 | 495 |
505 bool CanObserveMinusZero(MachineTypeUnion use) { | 496 bool CanObserveMinusZero(MachineTypeUnion use) { |
506 // TODO(turbofan): technically Uint32 cannot observe minus zero either. | 497 // TODO(turbofan): technically Uint32 cannot observe minus zero either. |
507 return (use & (kTypeUint32 | kTypeNumber | kTypeAny)) != 0; | 498 return (use & (kTypeUint32 | kTypeNumber | kTypeAny)) != 0; |
508 } | 499 } |
509 | 500 |
510 bool CanObserveNaN(MachineTypeUnion use) { | 501 bool CanObserveNaN(MachineTypeUnion use) { |
511 return (use & (kTypeNumber | kTypeAny)) != 0; | 502 return (use & (kTypeNumber | kTypeAny)) != 0; |
512 } | 503 } |
513 | 504 |
514 bool CanObserveNonUint32(MachineTypeUnion use) { | |
515 return (use & (kTypeInt32 | kTypeNumber | kTypeAny)) != 0; | |
516 } | |
517 | |
518 // Dispatching routine for visiting the node {node} with the usage {use}. | 505 // Dispatching routine for visiting the node {node} with the usage {use}. |
519 // Depending on the operator, propagate new usage info to the inputs. | 506 // Depending on the operator, propagate new usage info to the inputs. |
520 void VisitNode(Node* node, MachineTypeUnion use, | 507 void VisitNode(Node* node, MachineTypeUnion use, |
521 SimplifiedLowering* lowering) { | 508 SimplifiedLowering* lowering) { |
522 switch (node->opcode()) { | 509 switch (node->opcode()) { |
523 //------------------------------------------------------------------ | 510 //------------------------------------------------------------------ |
524 // Common operators. | 511 // Common operators. |
525 //------------------------------------------------------------------ | 512 //------------------------------------------------------------------ |
526 case IrOpcode::kStart: | 513 case IrOpcode::kStart: |
527 case IrOpcode::kDead: | 514 case IrOpcode::kDead: |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
637 break; | 624 break; |
638 } | 625 } |
639 case IrOpcode::kNumberAdd: | 626 case IrOpcode::kNumberAdd: |
640 case IrOpcode::kNumberSubtract: { | 627 case IrOpcode::kNumberSubtract: { |
641 // Add and subtract reduce to Int32Add/Sub if the inputs | 628 // Add and subtract reduce to Int32Add/Sub if the inputs |
642 // are already integers and all uses are truncating. | 629 // are already integers and all uses are truncating. |
643 if (CanLowerToInt32Binop(node, use)) { | 630 if (CanLowerToInt32Binop(node, use)) { |
644 // => signed Int32Add/Sub | 631 // => signed Int32Add/Sub |
645 VisitInt32Binop(node); | 632 VisitInt32Binop(node); |
646 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); | 633 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); |
647 } else if (CanLowerToInt32AdditiveBinop(node, use)) { | 634 } else if (CanLowerToUint32Binop(node, use)) { |
| 635 // => unsigned Int32Add/Sub |
| 636 VisitUint32Binop(node); |
| 637 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node)); |
| 638 } else if (CanLowerToWord32AdditiveBinop(node, use)) { |
648 // => signed Int32Add/Sub, truncating inputs | 639 // => signed Int32Add/Sub, truncating inputs |
649 ProcessTruncateWord32Input(node, 0, kTypeInt32); | 640 ProcessTruncateWord32Input(node, 0, kTypeInt32); |
650 ProcessTruncateWord32Input(node, 1, kTypeInt32); | 641 ProcessTruncateWord32Input(node, 1, kTypeInt32); |
651 SetOutput(node, kMachInt32); | 642 SetOutput(node, kMachInt32); |
652 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); | 643 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); |
653 } else if (CanLowerToUint32Binop(node, use)) { | |
654 // => unsigned Int32Add/Sub | |
655 VisitUint32Binop(node); | |
656 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node)); | |
657 } else if (CanLowerToUint32AdditiveBinop(node, use)) { | |
658 // => signed Int32Add/Sub, truncating inputs | |
659 ProcessTruncateWord32Input(node, 0, kTypeUint32); | |
660 ProcessTruncateWord32Input(node, 1, kTypeUint32); | |
661 SetOutput(node, kMachUint32); | |
662 if (lower()) NodeProperties::ChangeOp(node, Uint32Op(node)); | |
663 } else { | 644 } else { |
664 // => Float64Add/Sub | 645 // => Float64Add/Sub |
665 VisitFloat64Binop(node); | 646 VisitFloat64Binop(node); |
666 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); | 647 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); |
667 } | 648 } |
668 break; | 649 break; |
669 } | 650 } |
670 case IrOpcode::kNumberMultiply: { | 651 case IrOpcode::kNumberMultiply: { |
671 NumberMatcher right(node->InputAt(1)); | 652 NumberMatcher right(node->InputAt(1)); |
672 if (right.IsInRange(-1048576, 1048576)) { // must fit double mantissa. | 653 if (right.IsInRange(-1048576, 1048576)) { // must fit double mantissa. |
(...skipping 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1698 ReplaceEffectUses(node, comparison); | 1679 ReplaceEffectUses(node, comparison); |
1699 node->ReplaceInput(0, comparison); | 1680 node->ReplaceInput(0, comparison); |
1700 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1681 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
1701 node->TrimInputCount(2); | 1682 node->TrimInputCount(2); |
1702 NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual()); | 1683 NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual()); |
1703 } | 1684 } |
1704 | 1685 |
1705 } // namespace compiler | 1686 } // namespace compiler |
1706 } // namespace internal | 1687 } // namespace internal |
1707 } // namespace v8 | 1688 } // namespace v8 |
OLD | NEW |