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 |