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" |
11 #include "src/compiler/common-operator.h" | 11 #include "src/compiler/common-operator.h" |
12 #include "src/compiler/diamond.h" | 12 #include "src/compiler/diamond.h" |
13 #include "src/compiler/linkage.h" | 13 #include "src/compiler/linkage.h" |
14 #include "src/compiler/node-matchers.h" | 14 #include "src/compiler/node-matchers.h" |
15 #include "src/compiler/node-properties.h" | 15 #include "src/compiler/node-properties.h" |
16 #include "src/compiler/operator-properties.h" | 16 #include "src/compiler/operator-properties.h" |
17 #include "src/compiler/representation-change.h" | 17 #include "src/compiler/representation-change.h" |
18 #include "src/compiler/simplified-operator.h" | 18 #include "src/compiler/simplified-operator.h" |
19 #include "src/compiler/source-position.h" | 19 #include "src/compiler/source-position.h" |
20 #include "src/objects.h" | 20 #include "src/objects.h" |
| 21 #include "src/type-cache.h" |
21 | 22 |
22 namespace v8 { | 23 namespace v8 { |
23 namespace internal { | 24 namespace internal { |
24 namespace compiler { | 25 namespace compiler { |
25 | 26 |
26 // Macro for outputting trace information from representation inference. | 27 // Macro for outputting trace information from representation inference. |
27 #define TRACE(...) \ | 28 #define TRACE(...) \ |
28 do { \ | 29 do { \ |
29 if (FLAG_trace_representation) PrintF(__VA_ARGS__); \ | 30 if (FLAG_trace_representation) PrintF(__VA_ARGS__); \ |
30 } while (false) | 31 } while (false) |
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
188 RepresentationChanger* changer, | 189 RepresentationChanger* changer, |
189 SourcePositionTable* source_positions) | 190 SourcePositionTable* source_positions) |
190 : jsgraph_(jsgraph), | 191 : jsgraph_(jsgraph), |
191 count_(jsgraph->graph()->NodeCount()), | 192 count_(jsgraph->graph()->NodeCount()), |
192 info_(count_, zone), | 193 info_(count_, zone), |
193 nodes_(zone), | 194 nodes_(zone), |
194 replacements_(zone), | 195 replacements_(zone), |
195 phase_(PROPAGATE), | 196 phase_(PROPAGATE), |
196 changer_(changer), | 197 changer_(changer), |
197 queue_(zone), | 198 queue_(zone), |
198 source_positions_(source_positions) { | 199 source_positions_(source_positions), |
199 safe_int_additive_range_ = | 200 type_cache_(TypeCache::Get()) {} |
200 Type::Range(-std::pow(2.0, 52.0), std::pow(2.0, 52.0), zone); | |
201 } | |
202 | 201 |
203 void Run(SimplifiedLowering* lowering) { | 202 void Run(SimplifiedLowering* lowering) { |
204 // Run propagation phase to a fixpoint. | 203 // Run propagation phase to a fixpoint. |
205 TRACE("--{Propagation phase}--\n"); | 204 TRACE("--{Propagation phase}--\n"); |
206 phase_ = PROPAGATE; | 205 phase_ = PROPAGATE; |
207 Enqueue(jsgraph_->graph()->end()); | 206 Enqueue(jsgraph_->graph()->end()); |
208 // Process nodes from the queue until it is empty. | 207 // Process nodes from the queue until it is empty. |
209 while (!queue_.empty()) { | 208 while (!queue_.empty()) { |
210 Node* node = queue_.front(); | 209 Node* node = queue_.front(); |
211 NodeInfo* info = GetInfo(node); | 210 NodeInfo* info = GetInfo(node); |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
560 } | 559 } |
561 | 560 |
562 bool CanLowerToInt32AdditiveBinop(Node* node, Truncation use) { | 561 bool CanLowerToInt32AdditiveBinop(Node* node, Truncation use) { |
563 // It is safe to lower to word32 operation if: | 562 // It is safe to lower to word32 operation if: |
564 // - the inputs are safe integers (so the low bits are not discarded), and | 563 // - the inputs are safe integers (so the low bits are not discarded), and |
565 // - the uses can only observe the lowest 32 bits or they can recover the | 564 // - the uses can only observe the lowest 32 bits or they can recover the |
566 // the value from the type. | 565 // the value from the type. |
567 // TODO(jarin): we could support the uint32 case here, but that would | 566 // TODO(jarin): we could support the uint32 case here, but that would |
568 // require setting kTypeUint32 as the output type. Eventually, we will want | 567 // require setting kTypeUint32 as the output type. Eventually, we will want |
569 // to use only the big types, then this should work automatically. | 568 // to use only the big types, then this should work automatically. |
570 return BothInputsAre(node, safe_int_additive_range_) && | 569 return BothInputsAre(node, type_cache_.kAdditiveSafeInteger) && |
571 (use.TruncatesToWord32() || | 570 (use.TruncatesToWord32() || |
572 NodeProperties::GetType(node)->Is(Type::Signed32())); | 571 NodeProperties::GetType(node)->Is(Type::Signed32())); |
573 } | 572 } |
574 | 573 |
| 574 bool CanLowerToInt32MultiplicativeBinop(Node* node, Truncation use) { |
| 575 return BothInputsAre(node, Type::Signed32()) && |
| 576 (NodeProperties::GetType(node)->Is(Type::Signed32()) || |
| 577 (use.TruncatesToWord32() && |
| 578 NodeProperties::GetType(node)->Is(type_cache_.kSafeInteger))); |
| 579 } |
| 580 |
575 // Dispatching routine for visiting the node {node} with the usage {use}. | 581 // Dispatching routine for visiting the node {node} with the usage {use}. |
576 // Depending on the operator, propagate new usage info to the inputs. | 582 // Depending on the operator, propagate new usage info to the inputs. |
577 void VisitNode(Node* node, Truncation truncation, | 583 void VisitNode(Node* node, Truncation truncation, |
578 SimplifiedLowering* lowering) { | 584 SimplifiedLowering* lowering) { |
579 switch (node->opcode()) { | 585 switch (node->opcode()) { |
580 //------------------------------------------------------------------ | 586 //------------------------------------------------------------------ |
581 // Common operators. | 587 // Common operators. |
582 //------------------------------------------------------------------ | 588 //------------------------------------------------------------------ |
583 case IrOpcode::kStart: | 589 case IrOpcode::kStart: |
584 case IrOpcode::kDead: | 590 case IrOpcode::kDead: |
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
702 VisitInt32Binop(node); | 708 VisitInt32Binop(node); |
703 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); | 709 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); |
704 } else { | 710 } else { |
705 // => Float64Add/Sub | 711 // => Float64Add/Sub |
706 VisitFloat64Binop(node); | 712 VisitFloat64Binop(node); |
707 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); | 713 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); |
708 } | 714 } |
709 break; | 715 break; |
710 } | 716 } |
711 case IrOpcode::kNumberMultiply: { | 717 case IrOpcode::kNumberMultiply: { |
712 NumberMatcher right(node->InputAt(1)); | 718 // Multiply reduces to Int32Mul if the inputs are |
713 if (right.IsInRange(-1048576, 1048576)) { // must fit double mantissa. | 719 // already integers and all uses are truncating. |
714 if (CanLowerToInt32Binop(node, truncation)) { | 720 if (CanLowerToInt32MultiplicativeBinop(node, truncation)) { |
715 // => signed Int32Mul | 721 // => signed Int32Mul |
716 VisitInt32Binop(node); | 722 VisitInt32Binop(node); |
717 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); | 723 if (lower()) NodeProperties::ChangeOp(node, Int32Op(node)); |
718 break; | 724 } else { |
719 } | 725 // => Float64Mul |
| 726 VisitFloat64Binop(node); |
| 727 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); |
720 } | 728 } |
721 // => Float64Mul | |
722 VisitFloat64Binop(node); | |
723 if (lower()) NodeProperties::ChangeOp(node, Float64Op(node)); | |
724 break; | 729 break; |
725 } | 730 } |
726 case IrOpcode::kNumberDivide: { | 731 case IrOpcode::kNumberDivide: { |
727 if (CanLowerToInt32Binop(node, truncation)) { | 732 if (CanLowerToInt32Binop(node, truncation)) { |
728 // => signed Int32Div | 733 // => signed Int32Div |
729 VisitInt32Binop(node); | 734 VisitInt32Binop(node); |
730 if (lower()) DeferReplacement(node, lowering->Int32Div(node)); | 735 if (lower()) DeferReplacement(node, lowering->Int32Div(node)); |
731 break; | 736 break; |
732 } | 737 } |
733 if (BothInputsAre(node, Type::Unsigned32()) && | 738 if (BothInputsAre(node, Type::Unsigned32()) && |
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1153 NodeVector replacements_; // replacements to be done after lowering | 1158 NodeVector replacements_; // replacements to be done after lowering |
1154 Phase phase_; // current phase of algorithm | 1159 Phase phase_; // current phase of algorithm |
1155 RepresentationChanger* changer_; // for inserting representation changes | 1160 RepresentationChanger* changer_; // for inserting representation changes |
1156 ZoneQueue<Node*> queue_; // queue for traversing the graph | 1161 ZoneQueue<Node*> queue_; // queue for traversing the graph |
1157 // TODO(danno): RepresentationSelector shouldn't know anything about the | 1162 // TODO(danno): RepresentationSelector shouldn't know anything about the |
1158 // source positions table, but must for now since there currently is no other | 1163 // source positions table, but must for now since there currently is no other |
1159 // way to pass down source position information to nodes created during | 1164 // way to pass down source position information to nodes created during |
1160 // lowering. Once this phase becomes a vanilla reducer, it should get source | 1165 // lowering. Once this phase becomes a vanilla reducer, it should get source |
1161 // position information via the SourcePositionWrapper like all other reducers. | 1166 // position information via the SourcePositionWrapper like all other reducers. |
1162 SourcePositionTable* source_positions_; | 1167 SourcePositionTable* source_positions_; |
1163 Type* safe_int_additive_range_; | 1168 TypeCache const& type_cache_; |
1164 | 1169 |
1165 NodeInfo* GetInfo(Node* node) { | 1170 NodeInfo* GetInfo(Node* node) { |
1166 DCHECK(node->id() >= 0); | 1171 DCHECK(node->id() >= 0); |
1167 DCHECK(node->id() < count_); | 1172 DCHECK(node->id() < count_); |
1168 return &info_[node->id()]; | 1173 return &info_[node->id()]; |
1169 } | 1174 } |
1170 }; | 1175 }; |
1171 | 1176 |
1172 | 1177 |
1173 SimplifiedLowering::SimplifiedLowering(JSGraph* jsgraph, Zone* zone, | 1178 SimplifiedLowering::SimplifiedLowering(JSGraph* jsgraph, Zone* zone, |
1174 SourcePositionTable* source_positions) | 1179 SourcePositionTable* source_positions) |
1175 : jsgraph_(jsgraph), | 1180 : jsgraph_(jsgraph), |
1176 zone_(zone), | 1181 zone_(zone), |
1177 zero_thirtyone_range_(Type::Range(0, 31, zone)), | 1182 type_cache_(TypeCache::Get()), |
1178 source_positions_(source_positions) {} | 1183 source_positions_(source_positions) {} |
1179 | 1184 |
1180 | 1185 |
1181 void SimplifiedLowering::LowerAllNodes() { | 1186 void SimplifiedLowering::LowerAllNodes() { |
1182 RepresentationChanger changer(jsgraph(), jsgraph()->isolate()); | 1187 RepresentationChanger changer(jsgraph(), jsgraph()->isolate()); |
1183 RepresentationSelector selector(jsgraph(), zone_, &changer, | 1188 RepresentationSelector selector(jsgraph(), zone_, &changer, |
1184 source_positions_); | 1189 source_positions_); |
1185 selector.Run(this); | 1190 selector.Run(this); |
1186 } | 1191 } |
1187 | 1192 |
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1548 Node* false0 = zero; | 1553 Node* false0 = zero; |
1549 | 1554 |
1550 Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0); | 1555 Node* merge0 = graph()->NewNode(merge_op, if_true0, if_false0); |
1551 return graph()->NewNode(phi_op, true0, false0, merge0); | 1556 return graph()->NewNode(phi_op, true0, false0, merge0); |
1552 } | 1557 } |
1553 | 1558 |
1554 | 1559 |
1555 void SimplifiedLowering::DoShift(Node* node, Operator const* op) { | 1560 void SimplifiedLowering::DoShift(Node* node, Operator const* op) { |
1556 Node* const rhs = NodeProperties::GetValueInput(node, 1); | 1561 Node* const rhs = NodeProperties::GetValueInput(node, 1); |
1557 Type* const rhs_type = NodeProperties::GetType(rhs); | 1562 Type* const rhs_type = NodeProperties::GetType(rhs); |
1558 if (!rhs_type->Is(zero_thirtyone_range_)) { | 1563 if (!rhs_type->Is(type_cache_.kZeroToThirtyOne)) { |
1559 node->ReplaceInput(1, graph()->NewNode(machine()->Word32And(), rhs, | 1564 node->ReplaceInput(1, graph()->NewNode(machine()->Word32And(), rhs, |
1560 jsgraph()->Int32Constant(0x1f))); | 1565 jsgraph()->Int32Constant(0x1f))); |
1561 } | 1566 } |
1562 NodeProperties::ChangeOp(node, op); | 1567 NodeProperties::ChangeOp(node, op); |
1563 } | 1568 } |
1564 | 1569 |
1565 | 1570 |
1566 namespace { | 1571 namespace { |
1567 | 1572 |
1568 void ReplaceEffectUses(Node* node, Node* replacement) { | 1573 void ReplaceEffectUses(Node* node, Node* replacement) { |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1605 ReplaceEffectUses(node, comparison); | 1610 ReplaceEffectUses(node, comparison); |
1606 node->ReplaceInput(0, comparison); | 1611 node->ReplaceInput(0, comparison); |
1607 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); | 1612 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); |
1608 node->TrimInputCount(2); | 1613 node->TrimInputCount(2); |
1609 NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual()); | 1614 NodeProperties::ChangeOp(node, machine()->IntLessThanOrEqual()); |
1610 } | 1615 } |
1611 | 1616 |
1612 } // namespace compiler | 1617 } // namespace compiler |
1613 } // namespace internal | 1618 } // namespace internal |
1614 } // namespace v8 | 1619 } // namespace v8 |
OLD | NEW |