| 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/compiler/access-builder.h" | 6 #include "src/compiler/access-builder.h" |
| 7 #include "src/compiler/js-graph.h" | 7 #include "src/compiler/js-graph.h" |
| 8 #include "src/compiler/js-typed-lowering.h" | 8 #include "src/compiler/js-typed-lowering.h" |
| 9 #include "src/compiler/linkage.h" | 9 #include "src/compiler/linkage.h" |
| 10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
| 11 #include "src/compiler/node-properties.h" | 11 #include "src/compiler/node-properties.h" |
| 12 #include "src/compiler/operator-properties.h" | 12 #include "src/compiler/operator-properties.h" |
| 13 #include "src/types.h" | 13 #include "src/types.h" |
| 14 | 14 |
| 15 namespace v8 { | 15 namespace v8 { |
| 16 namespace internal { | 16 namespace internal { |
| 17 namespace compiler { | 17 namespace compiler { |
| 18 | 18 |
| 19 // TODO(turbofan): js-typed-lowering improvements possible | 19 // TODO(turbofan): js-typed-lowering improvements possible |
| 20 // - immediately put in type bounds for all new nodes | 20 // - immediately put in type bounds for all new nodes |
| 21 // - relax effects from generic but not-side-effecting operations | 21 // - relax effects from generic but not-side-effecting operations |
| 22 | 22 |
| 23 | 23 |
| 24 JSTypedLowering::JSTypedLowering(Editor* editor, JSGraph* jsgraph, Zone* zone) | 24 JSTypedLowering::JSTypedLowering(Editor* editor, JSGraph* jsgraph, Zone* zone) |
| 25 : AdvancedReducer(editor), jsgraph_(jsgraph), simplified_(graph()->zone()) { | 25 : AdvancedReducer(editor), jsgraph_(jsgraph), simplified_(graph()->zone()) { |
| 26 zero_range_ = Type::Range(0.0, 0.0, graph()->zone()); | |
| 27 one_range_ = Type::Range(1.0, 1.0, graph()->zone()); | |
| 28 zero_thirtyone_range_ = Type::Range(0.0, 31.0, graph()->zone()); | |
| 29 for (size_t k = 0; k < arraysize(shifted_int32_ranges_); ++k) { | 26 for (size_t k = 0; k < arraysize(shifted_int32_ranges_); ++k) { |
| 30 double min = kMinInt / (1 << k); | 27 double min = kMinInt / (1 << k); |
| 31 double max = kMaxInt / (1 << k); | 28 double max = kMaxInt / (1 << k); |
| 32 shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone()); | 29 shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone()); |
| 33 } | 30 } |
| 34 } | 31 } |
| 35 | 32 |
| 36 | 33 |
| 37 // A helper class to construct inline allocations on the simplified operator | 34 // A helper class to construct inline allocations on the simplified operator |
| 38 // level. This keeps track of the effect chain for initial stores on a newly | 35 // level. This keeps track of the effect chain for initial stores on a newly |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 Signedness right_signedness) { | 132 Signedness right_signedness) { |
| 136 node_->ReplaceInput(0, ConvertToUI32(left(), left_signedness)); | 133 node_->ReplaceInput(0, ConvertToUI32(left(), left_signedness)); |
| 137 node_->ReplaceInput(1, ConvertToUI32(right(), right_signedness)); | 134 node_->ReplaceInput(1, ConvertToUI32(right(), right_signedness)); |
| 138 } | 135 } |
| 139 | 136 |
| 140 void ConvertInputsToString() { | 137 void ConvertInputsToString() { |
| 141 node_->ReplaceInput(0, ConvertToString(left())); | 138 node_->ReplaceInput(0, ConvertToString(left())); |
| 142 node_->ReplaceInput(1, ConvertToString(right())); | 139 node_->ReplaceInput(1, ConvertToString(right())); |
| 143 } | 140 } |
| 144 | 141 |
| 145 // Convert inputs for bitwise shift operation (ES5 spec 11.7). | |
| 146 void ConvertInputsForShift(Signedness left_signedness) { | |
| 147 node_->ReplaceInput(0, ConvertToUI32(ConvertPlainPrimitiveToNumber(left()), | |
| 148 left_signedness)); | |
| 149 Node* rnum = | |
| 150 ConvertToUI32(ConvertPlainPrimitiveToNumber(right()), kUnsigned); | |
| 151 Type* rnum_type = NodeProperties::GetBounds(rnum).upper; | |
| 152 if (!rnum_type->Is(lowering_->zero_thirtyone_range_)) { | |
| 153 rnum = graph()->NewNode(machine()->Word32And(), rnum, | |
| 154 jsgraph()->Int32Constant(0x1F)); | |
| 155 } | |
| 156 node_->ReplaceInput(1, rnum); | |
| 157 } | |
| 158 | |
| 159 void SwapInputs() { | 142 void SwapInputs() { |
| 160 Node* l = left(); | 143 Node* l = left(); |
| 161 Node* r = right(); | 144 Node* r = right(); |
| 162 node_->ReplaceInput(0, r); | 145 node_->ReplaceInput(0, r); |
| 163 node_->ReplaceInput(1, l); | 146 node_->ReplaceInput(1, l); |
| 164 } | 147 } |
| 165 | 148 |
| 166 // Remove all effect and control inputs and outputs to this node and change | 149 // Remove all effect and control inputs and outputs to this node and change |
| 167 // to the pure operator {op}, possibly inserting a boolean inversion. | 150 // to the pure operator {op}, possibly inserting a boolean inversion. |
| 168 Reduction ChangeToPureOperator(const Operator* op, bool invert = false, | 151 Reduction ChangeToPureOperator(const Operator* op, bool invert = false, |
| (...skipping 312 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 481 return r.ChangeToPureOperator(intOp, Type::Integral32()); | 464 return r.ChangeToPureOperator(intOp, Type::Integral32()); |
| 482 } | 465 } |
| 483 | 466 |
| 484 | 467 |
| 485 Reduction JSTypedLowering::ReduceUI32Shift(Node* node, | 468 Reduction JSTypedLowering::ReduceUI32Shift(Node* node, |
| 486 Signedness left_signedness, | 469 Signedness left_signedness, |
| 487 const Operator* shift_op) { | 470 const Operator* shift_op) { |
| 488 JSBinopReduction r(this, node); | 471 JSBinopReduction r(this, node); |
| 489 if (r.IsStrong()) { | 472 if (r.IsStrong()) { |
| 490 if (r.BothInputsAre(Type::Number())) { | 473 if (r.BothInputsAre(Type::Number())) { |
| 491 r.ConvertInputsForShift(left_signedness); | 474 r.ConvertInputsToUI32(left_signedness, kUnsigned); |
| 492 return r.ChangeToPureOperator(shift_op); | 475 return r.ChangeToPureOperator(shift_op); |
| 493 } | 476 } |
| 494 return NoChange(); | 477 return NoChange(); |
| 495 } | 478 } |
| 496 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); | 479 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); |
| 497 r.ConvertInputsToNumber(frame_state); | 480 r.ConvertInputsToNumber(frame_state); |
| 498 r.ConvertInputsForShift(left_signedness); | 481 r.ConvertInputsToUI32(left_signedness, kUnsigned); |
| 499 return r.ChangeToPureOperator(shift_op); | 482 return r.ChangeToPureOperator(shift_op); |
| 500 } | 483 } |
| 501 | 484 |
| 502 | 485 |
| 503 Reduction JSTypedLowering::ReduceJSComparison(Node* node) { | 486 Reduction JSTypedLowering::ReduceJSComparison(Node* node) { |
| 504 JSBinopReduction r(this, node); | 487 JSBinopReduction r(this, node); |
| 505 if (r.BothInputsAre(Type::String())) { | 488 if (r.BothInputsAre(Type::String())) { |
| 506 // If both inputs are definitely strings, perform a string comparison. | 489 // If both inputs are definitely strings, perform a string comparison. |
| 507 const Operator* stringOp; | 490 const Operator* stringOp; |
| 508 switch (node->opcode()) { | 491 switch (node->opcode()) { |
| (...skipping 1096 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1605 case IrOpcode::kJSLessThanOrEqual: // fall through | 1588 case IrOpcode::kJSLessThanOrEqual: // fall through |
| 1606 case IrOpcode::kJSGreaterThanOrEqual: | 1589 case IrOpcode::kJSGreaterThanOrEqual: |
| 1607 return ReduceJSComparison(node); | 1590 return ReduceJSComparison(node); |
| 1608 case IrOpcode::kJSBitwiseOr: | 1591 case IrOpcode::kJSBitwiseOr: |
| 1609 return ReduceInt32Binop(node, machine()->Word32Or()); | 1592 return ReduceInt32Binop(node, machine()->Word32Or()); |
| 1610 case IrOpcode::kJSBitwiseXor: | 1593 case IrOpcode::kJSBitwiseXor: |
| 1611 return ReduceInt32Binop(node, machine()->Word32Xor()); | 1594 return ReduceInt32Binop(node, machine()->Word32Xor()); |
| 1612 case IrOpcode::kJSBitwiseAnd: | 1595 case IrOpcode::kJSBitwiseAnd: |
| 1613 return ReduceInt32Binop(node, machine()->Word32And()); | 1596 return ReduceInt32Binop(node, machine()->Word32And()); |
| 1614 case IrOpcode::kJSShiftLeft: | 1597 case IrOpcode::kJSShiftLeft: |
| 1615 return ReduceUI32Shift(node, kSigned, machine()->Word32Shl()); | 1598 return ReduceUI32Shift(node, kSigned, simplified()->NumberShiftLeft()); |
| 1616 case IrOpcode::kJSShiftRight: | 1599 case IrOpcode::kJSShiftRight: |
| 1617 return ReduceUI32Shift(node, kSigned, machine()->Word32Sar()); | 1600 return ReduceUI32Shift(node, kSigned, simplified()->NumberShiftRight()); |
| 1618 case IrOpcode::kJSShiftRightLogical: | 1601 case IrOpcode::kJSShiftRightLogical: |
| 1619 return ReduceUI32Shift(node, kUnsigned, machine()->Word32Shr()); | 1602 return ReduceUI32Shift(node, kUnsigned, |
| 1603 simplified()->NumberShiftRightLogical()); |
| 1620 case IrOpcode::kJSAdd: | 1604 case IrOpcode::kJSAdd: |
| 1621 return ReduceJSAdd(node); | 1605 return ReduceJSAdd(node); |
| 1622 case IrOpcode::kJSSubtract: | 1606 case IrOpcode::kJSSubtract: |
| 1623 return ReduceNumberBinop(node, simplified()->NumberSubtract()); | 1607 return ReduceNumberBinop(node, simplified()->NumberSubtract()); |
| 1624 case IrOpcode::kJSMultiply: | 1608 case IrOpcode::kJSMultiply: |
| 1625 return ReduceNumberBinop(node, simplified()->NumberMultiply()); | 1609 return ReduceNumberBinop(node, simplified()->NumberMultiply()); |
| 1626 case IrOpcode::kJSDivide: | 1610 case IrOpcode::kJSDivide: |
| 1627 return ReduceNumberBinop(node, simplified()->NumberDivide()); | 1611 return ReduceNumberBinop(node, simplified()->NumberDivide()); |
| 1628 case IrOpcode::kJSModulus: | 1612 case IrOpcode::kJSModulus: |
| 1629 return ReduceJSModulus(node); | 1613 return ReduceJSModulus(node); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1702 } | 1686 } |
| 1703 | 1687 |
| 1704 | 1688 |
| 1705 MachineOperatorBuilder* JSTypedLowering::machine() const { | 1689 MachineOperatorBuilder* JSTypedLowering::machine() const { |
| 1706 return jsgraph()->machine(); | 1690 return jsgraph()->machine(); |
| 1707 } | 1691 } |
| 1708 | 1692 |
| 1709 } // namespace compiler | 1693 } // namespace compiler |
| 1710 } // namespace internal | 1694 } // namespace internal |
| 1711 } // namespace v8 | 1695 } // namespace v8 |
| OLD | NEW |