| 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/code-factory.h" | 5 #include "src/code-factory.h" |
| 6 #include "src/compilation-dependencies.h" | 6 #include "src/compilation-dependencies.h" |
| 7 #include "src/compiler/access-builder.h" | 7 #include "src/compiler/access-builder.h" |
| 8 #include "src/compiler/js-graph.h" | 8 #include "src/compiler/js-graph.h" |
| 9 #include "src/compiler/js-typed-lowering.h" | 9 #include "src/compiler/js-typed-lowering.h" |
| 10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 100 // Insert an boolean not to invert the value. | 100 // Insert an boolean not to invert the value. |
| 101 Node* value = graph()->NewNode(simplified()->BooleanNot(), node_); | 101 Node* value = graph()->NewNode(simplified()->BooleanNot(), node_); |
| 102 node_->ReplaceUses(value); | 102 node_->ReplaceUses(value); |
| 103 // Note: ReplaceUses() smashes all uses, so smash it back here. | 103 // Note: ReplaceUses() smashes all uses, so smash it back here. |
| 104 value->ReplaceInput(0, node_); | 104 value->ReplaceInput(0, node_); |
| 105 return lowering_->Replace(value); | 105 return lowering_->Replace(value); |
| 106 } | 106 } |
| 107 return lowering_->Changed(node_); | 107 return lowering_->Changed(node_); |
| 108 } | 108 } |
| 109 | 109 |
| 110 Reduction ChangeToStringComparisonOperator(const Operator* op, | |
| 111 bool invert = false) { | |
| 112 if (node_->op()->ControlInputCount() > 0) { | |
| 113 lowering_->RelaxControls(node_); | |
| 114 } | |
| 115 // String comparison operators need effect and control inputs, so copy them | |
| 116 // over. | |
| 117 Node* effect = NodeProperties::GetEffectInput(node_); | |
| 118 Node* control = NodeProperties::GetControlInput(node_); | |
| 119 node_->ReplaceInput(2, effect); | |
| 120 node_->ReplaceInput(3, control); | |
| 121 | |
| 122 node_->TrimInputCount(4); | |
| 123 NodeProperties::ChangeOp(node_, op); | |
| 124 | |
| 125 if (invert) { | |
| 126 // Insert a boolean-not to invert the value. | |
| 127 Node* value = graph()->NewNode(simplified()->BooleanNot(), node_); | |
| 128 node_->ReplaceUses(value); | |
| 129 // Note: ReplaceUses() smashes all uses, so smash it back here. | |
| 130 value->ReplaceInput(0, node_); | |
| 131 return lowering_->Replace(value); | |
| 132 } | |
| 133 return lowering_->Changed(node_); | |
| 134 } | |
| 135 | |
| 136 Reduction ChangeToPureOperator(const Operator* op, Type* type) { | 110 Reduction ChangeToPureOperator(const Operator* op, Type* type) { |
| 137 return ChangeToPureOperator(op, false, type); | 111 return ChangeToPureOperator(op, false, type); |
| 138 } | 112 } |
| 139 | 113 |
| 140 bool LeftInputIs(Type* t) { return left_type()->Is(t); } | 114 bool LeftInputIs(Type* t) { return left_type()->Is(t); } |
| 141 | 115 |
| 142 bool RightInputIs(Type* t) { return right_type()->Is(t); } | 116 bool RightInputIs(Type* t) { return right_type()->Is(t); } |
| 143 | 117 |
| 144 bool OneInputIs(Type* t) { return LeftInputIs(t) || RightInputIs(t); } | 118 bool OneInputIs(Type* t) { return LeftInputIs(t) || RightInputIs(t); } |
| 145 | 119 |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 case IrOpcode::kJSLessThanOrEqual: | 444 case IrOpcode::kJSLessThanOrEqual: |
| 471 stringOp = simplified()->StringLessThanOrEqual(); | 445 stringOp = simplified()->StringLessThanOrEqual(); |
| 472 break; | 446 break; |
| 473 case IrOpcode::kJSGreaterThanOrEqual: | 447 case IrOpcode::kJSGreaterThanOrEqual: |
| 474 stringOp = simplified()->StringLessThanOrEqual(); | 448 stringOp = simplified()->StringLessThanOrEqual(); |
| 475 r.SwapInputs(); // a >= b => b <= a | 449 r.SwapInputs(); // a >= b => b <= a |
| 476 break; | 450 break; |
| 477 default: | 451 default: |
| 478 return NoChange(); | 452 return NoChange(); |
| 479 } | 453 } |
| 480 r.ChangeToStringComparisonOperator(stringOp); | 454 r.ChangeToPureOperator(stringOp); |
| 481 return Changed(node); | 455 return Changed(node); |
| 482 } | 456 } |
| 483 if (r.OneInputCannotBe(Type::StringOrReceiver())) { | 457 if (r.OneInputCannotBe(Type::StringOrReceiver())) { |
| 484 const Operator* less_than; | 458 const Operator* less_than; |
| 485 const Operator* less_than_or_equal; | 459 const Operator* less_than_or_equal; |
| 486 if (r.BothInputsAre(Type::Unsigned32())) { | 460 if (r.BothInputsAre(Type::Unsigned32())) { |
| 487 less_than = machine()->Uint32LessThan(); | 461 less_than = machine()->Uint32LessThan(); |
| 488 less_than_or_equal = machine()->Uint32LessThanOrEqual(); | 462 less_than_or_equal = machine()->Uint32LessThanOrEqual(); |
| 489 } else if (r.BothInputsAre(Type::Signed32())) { | 463 } else if (r.BothInputsAre(Type::Signed32())) { |
| 490 less_than = machine()->Int32LessThan(); | 464 less_than = machine()->Int32LessThan(); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 524 | 498 |
| 525 Reduction JSTypedLowering::ReduceJSEqual(Node* node, bool invert) { | 499 Reduction JSTypedLowering::ReduceJSEqual(Node* node, bool invert) { |
| 526 if (flags() & kDisableBinaryOpReduction) return NoChange(); | 500 if (flags() & kDisableBinaryOpReduction) return NoChange(); |
| 527 | 501 |
| 528 JSBinopReduction r(this, node); | 502 JSBinopReduction r(this, node); |
| 529 | 503 |
| 530 if (r.BothInputsAre(Type::Number())) { | 504 if (r.BothInputsAre(Type::Number())) { |
| 531 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); | 505 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); |
| 532 } | 506 } |
| 533 if (r.BothInputsAre(Type::String())) { | 507 if (r.BothInputsAre(Type::String())) { |
| 534 return r.ChangeToStringComparisonOperator(simplified()->StringEqual(), | 508 return r.ChangeToPureOperator(simplified()->StringEqual(), invert); |
| 535 invert); | |
| 536 } | 509 } |
| 537 if (r.BothInputsAre(Type::Boolean())) { | 510 if (r.BothInputsAre(Type::Boolean())) { |
| 538 return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Boolean()), | 511 return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Boolean()), |
| 539 invert); | 512 invert); |
| 540 } | 513 } |
| 541 if (r.BothInputsAre(Type::Receiver())) { | 514 if (r.BothInputsAre(Type::Receiver())) { |
| 542 return r.ChangeToPureOperator( | 515 return r.ChangeToPureOperator( |
| 543 simplified()->ReferenceEqual(Type::Receiver()), invert); | 516 simplified()->ReferenceEqual(Type::Receiver()), invert); |
| 544 } | 517 } |
| 545 if (r.OneInputIs(Type::Undetectable())) { | 518 if (r.OneInputIs(Type::Undetectable())) { |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 604 } | 577 } |
| 605 if (r.OneInputIs(Type::Receiver())) { | 578 if (r.OneInputIs(Type::Receiver())) { |
| 606 return r.ChangeToPureOperator( | 579 return r.ChangeToPureOperator( |
| 607 simplified()->ReferenceEqual(Type::Receiver()), invert); | 580 simplified()->ReferenceEqual(Type::Receiver()), invert); |
| 608 } | 581 } |
| 609 if (r.BothInputsAre(Type::Unique())) { | 582 if (r.BothInputsAre(Type::Unique())) { |
| 610 return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Unique()), | 583 return r.ChangeToPureOperator(simplified()->ReferenceEqual(Type::Unique()), |
| 611 invert); | 584 invert); |
| 612 } | 585 } |
| 613 if (r.BothInputsAre(Type::String())) { | 586 if (r.BothInputsAre(Type::String())) { |
| 614 return r.ChangeToStringComparisonOperator(simplified()->StringEqual(), | 587 return r.ChangeToPureOperator(simplified()->StringEqual(), invert); |
| 615 invert); | |
| 616 } | 588 } |
| 617 if (r.BothInputsAre(Type::NumberOrUndefined())) { | 589 if (r.BothInputsAre(Type::NumberOrUndefined())) { |
| 618 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); | 590 return r.ChangeToPureOperator(simplified()->NumberEqual(), invert); |
| 619 } | 591 } |
| 620 // TODO(turbofan): js-typed-lowering of StrictEqual(mixed types) | 592 // TODO(turbofan): js-typed-lowering of StrictEqual(mixed types) |
| 621 return NoChange(); | 593 return NoChange(); |
| 622 } | 594 } |
| 623 | 595 |
| 624 | 596 |
| 625 Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) { | 597 Reduction JSTypedLowering::ReduceJSToBoolean(Node* node) { |
| 626 Node* const input = node->InputAt(0); | 598 Node* const input = node->InputAt(0); |
| 627 Type* const input_type = NodeProperties::GetType(input); | 599 Type* const input_type = NodeProperties::GetType(input); |
| 628 Node* const effect = NodeProperties::GetEffectInput(node); | |
| 629 if (input_type->Is(Type::Boolean())) { | 600 if (input_type->Is(Type::Boolean())) { |
| 630 // JSToBoolean(x:boolean) => x | 601 // JSToBoolean(x:boolean) => x |
| 631 ReplaceWithValue(node, input, effect); | |
| 632 return Replace(input); | 602 return Replace(input); |
| 633 } else if (input_type->Is(Type::OrderedNumber())) { | 603 } else if (input_type->Is(Type::OrderedNumber())) { |
| 634 // JSToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x,#0)) | 604 // JSToBoolean(x:ordered-number) => BooleanNot(NumberEqual(x,#0)) |
| 635 RelaxEffectsAndControls(node); | 605 RelaxEffectsAndControls(node); |
| 636 node->ReplaceInput(0, graph()->NewNode(simplified()->NumberEqual(), input, | 606 node->ReplaceInput(0, graph()->NewNode(simplified()->NumberEqual(), input, |
| 637 jsgraph()->ZeroConstant())); | 607 jsgraph()->ZeroConstant())); |
| 638 node->TrimInputCount(1); | 608 node->TrimInputCount(1); |
| 639 NodeProperties::ChangeOp(node, simplified()->BooleanNot()); | 609 NodeProperties::ChangeOp(node, simplified()->BooleanNot()); |
| 640 return Changed(node); | 610 return Changed(node); |
| 641 } else if (input_type->Is(Type::String())) { | 611 } else if (input_type->Is(Type::String())) { |
| 642 // JSToBoolean(x:string) => NumberLessThan(#0,x.length) | 612 // JSToBoolean(x:string) => NumberLessThan(#0,x.length) |
| 643 FieldAccess const access = AccessBuilder::ForStringLength(); | 613 FieldAccess const access = AccessBuilder::ForStringLength(); |
| 644 Node* length = graph()->NewNode(simplified()->LoadField(access), input, | 614 Node* length = graph()->NewNode(simplified()->LoadField(access), input, |
| 645 effect, graph()->start()); | 615 graph()->start(), graph()->start()); |
| 646 ReplaceWithValue(node, node, length); | 616 ReplaceWithValue(node, node, length); |
| 647 node->ReplaceInput(0, jsgraph()->ZeroConstant()); | 617 node->ReplaceInput(0, jsgraph()->ZeroConstant()); |
| 648 node->ReplaceInput(1, length); | 618 node->ReplaceInput(1, length); |
| 649 node->TrimInputCount(2); | |
| 650 NodeProperties::ChangeOp(node, simplified()->NumberLessThan()); | 619 NodeProperties::ChangeOp(node, simplified()->NumberLessThan()); |
| 651 return Changed(node); | 620 return Changed(node); |
| 652 } | 621 } |
| 653 return NoChange(); | 622 return NoChange(); |
| 654 } | 623 } |
| 655 | 624 |
| 656 Reduction JSTypedLowering::ReduceJSToInteger(Node* node) { | 625 Reduction JSTypedLowering::ReduceJSToInteger(Node* node) { |
| 657 Node* const input = NodeProperties::GetValueInput(node, 0); | 626 Node* const input = NodeProperties::GetValueInput(node, 0); |
| 658 Type* const input_type = NodeProperties::GetType(input); | 627 Type* const input_type = NodeProperties::GetType(input); |
| 659 if (input_type->Is(type_cache_.kIntegerOrMinusZero)) { | 628 if (input_type->Is(type_cache_.kIntegerOrMinusZero)) { |
| (...skipping 1156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1816 } | 1785 } |
| 1817 | 1786 |
| 1818 | 1787 |
| 1819 CompilationDependencies* JSTypedLowering::dependencies() const { | 1788 CompilationDependencies* JSTypedLowering::dependencies() const { |
| 1820 return dependencies_; | 1789 return dependencies_; |
| 1821 } | 1790 } |
| 1822 | 1791 |
| 1823 } // namespace compiler | 1792 } // namespace compiler |
| 1824 } // namespace internal | 1793 } // namespace internal |
| 1825 } // namespace v8 | 1794 } // namespace v8 |
| OLD | NEW |