Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(283)

Side by Side Diff: src/compiler/simplified-lowering.cc

Issue 1478953002: [turbofan] Optimize truncated safe integer multiplications. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/simplified-lowering.h ('k') | src/type-cache.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/compiler/simplified-lowering.h ('k') | src/type-cache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698