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 |