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

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

Issue 636283009: [turbofan] Use range types to type and lower arithmetic ops. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rename MaybeWeaken and rebase Created 6 years, 2 months 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 | Annotate | Revision Log
« no previous file with comments | « src/compiler/representation-change.h ('k') | src/compiler/typer.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"
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
67 : jsgraph_(jsgraph), 67 : jsgraph_(jsgraph),
68 count_(jsgraph->graph()->NodeCount()), 68 count_(jsgraph->graph()->NodeCount()),
69 info_(zone->NewArray<NodeInfo>(count_)), 69 info_(zone->NewArray<NodeInfo>(count_)),
70 nodes_(zone), 70 nodes_(zone),
71 replacements_(zone), 71 replacements_(zone),
72 contains_js_nodes_(false), 72 contains_js_nodes_(false),
73 phase_(PROPAGATE), 73 phase_(PROPAGATE),
74 changer_(changer), 74 changer_(changer),
75 queue_(zone) { 75 queue_(zone) {
76 memset(info_, 0, sizeof(NodeInfo) * count_); 76 memset(info_, 0, sizeof(NodeInfo) * count_);
77
78 Factory* f = zone->isolate()->factory();
79 safe_int_additive_range_ =
80 Type::Range(f->NewNumber(-pow(2, 52)), f->NewNumber(pow(2, 52)), zone);
77 } 81 }
78 82
79 void Run(SimplifiedLowering* lowering) { 83 void Run(SimplifiedLowering* lowering) {
80 // Run propagation phase to a fixpoint. 84 // Run propagation phase to a fixpoint.
81 TRACE(("--{Propagation phase}--\n")); 85 TRACE(("--{Propagation phase}--\n"));
82 phase_ = PROPAGATE; 86 phase_ = PROPAGATE;
83 Enqueue(jsgraph_->graph()->end()); 87 Enqueue(jsgraph_->graph()->end());
84 // Process nodes from the queue until it is empty. 88 // Process nodes from the queue until it is empty.
85 while (!queue_.empty()) { 89 while (!queue_.empty()) {
86 Node* node = queue_.front(); 90 Node* node = queue_.front();
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
160 base::bits::IsPowerOfTwo32(output & kRepMask)); 164 base::bits::IsPowerOfTwo32(output & kRepMask));
161 GetInfo(node)->output = output; 165 GetInfo(node)->output = output;
162 } 166 }
163 167
164 bool BothInputsAre(Node* node, Type* type) { 168 bool BothInputsAre(Node* node, Type* type) {
165 DCHECK_EQ(2, node->InputCount()); 169 DCHECK_EQ(2, node->InputCount());
166 return NodeProperties::GetBounds(node->InputAt(0)).upper->Is(type) && 170 return NodeProperties::GetBounds(node->InputAt(0)).upper->Is(type) &&
167 NodeProperties::GetBounds(node->InputAt(1)).upper->Is(type); 171 NodeProperties::GetBounds(node->InputAt(1)).upper->Is(type);
168 } 172 }
169 173
174 void ProcessTruncateWord32Input(Node* node, int index, MachineTypeUnion use) {
175 Node* input = node->InputAt(index);
176 if (phase_ == PROPAGATE) {
177 // In the propagate phase, propagate the usage information backward.
178 Enqueue(input, use);
179 } else {
180 // In the change phase, insert a change before the use if necessary.
181 MachineTypeUnion output = GetInfo(input)->output;
182 if ((output & kRepWord32) == 0) {
183 // Output representation doesn't match usage.
184 TRACE((" truncate-to-int32: #%d:%s(@%d #%d:%s) ", node->id(),
185 node->op()->mnemonic(), index, input->id(),
186 input->op()->mnemonic()));
187 TRACE((" from "));
188 PrintInfo(output);
189 TRACE((" to "));
190 PrintInfo(use);
191 TRACE(("\n"));
192 Node* n = changer_->GetTruncatedWord32For(input, output);
193 node->ReplaceInput(index, n);
194 }
195 }
196 }
197
170 void ProcessInput(Node* node, int index, MachineTypeUnion use) { 198 void ProcessInput(Node* node, int index, MachineTypeUnion use) {
171 Node* input = node->InputAt(index); 199 Node* input = node->InputAt(index);
172 if (phase_ == PROPAGATE) { 200 if (phase_ == PROPAGATE) {
173 // In the propagate phase, propagate the usage information backward. 201 // In the propagate phase, propagate the usage information backward.
174 Enqueue(input, use); 202 Enqueue(input, use);
175 } else { 203 } else {
176 // In the change phase, insert a change before the use if necessary. 204 // In the change phase, insert a change before the use if necessary.
177 if ((use & kRepMask) == 0) return; // No input requirement on the use. 205 if ((use & kRepMask) == 0) return; // No input requirement on the use.
178 MachineTypeUnion output = GetInfo(input)->output; 206 MachineTypeUnion output = GetInfo(input)->output;
179 if ((output & kRepMask & use) == 0) { 207 if ((output & kRepMask & use) == 0) {
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 } 392 }
365 393
366 const Operator* Float64Op(Node* node) { 394 const Operator* Float64Op(Node* node) {
367 return changer_->Float64OperatorFor(node->opcode()); 395 return changer_->Float64OperatorFor(node->opcode());
368 } 396 }
369 397
370 bool CanLowerToInt32Binop(Node* node, MachineTypeUnion use) { 398 bool CanLowerToInt32Binop(Node* node, MachineTypeUnion use) {
371 return BothInputsAre(node, Type::Signed32()) && !CanObserveNonInt32(use); 399 return BothInputsAre(node, Type::Signed32()) && !CanObserveNonInt32(use);
372 } 400 }
373 401
402 bool IsSafeIntAdditiveOperand(Node* node) {
403 Type* type = NodeProperties::GetBounds(node).upper;
404 // TODO(jarin): Unfortunately, bitset types are not subtypes of larger
405 // range types, so we have to explicitly check for Integral32 here
406 // (in addition to the safe integer range). Once we fix subtyping for
407 // ranges, we should simplify this.
408 return type->Is(safe_int_additive_range_) || type->Is(Type::Integral32());
409 }
410
411 bool CanLowerToInt32AdditiveBinop(Node* node, MachineTypeUnion use) {
412 return IsSafeIntAdditiveOperand(node->InputAt(0)) &&
413 IsSafeIntAdditiveOperand(node->InputAt(1)) &&
414 !CanObserveNonInt32(use);
415 }
416
374 bool CanLowerToUint32Binop(Node* node, MachineTypeUnion use) { 417 bool CanLowerToUint32Binop(Node* node, MachineTypeUnion use) {
375 return BothInputsAre(node, Type::Unsigned32()) && !CanObserveNonUint32(use); 418 return BothInputsAre(node, Type::Unsigned32()) && !CanObserveNonUint32(use);
376 } 419 }
377 420
421 bool CanLowerToUint32AdditiveBinop(Node* node, MachineTypeUnion use) {
422 return IsSafeIntAdditiveOperand(node->InputAt(0)) &&
423 IsSafeIntAdditiveOperand(node->InputAt(1)) &&
424 !CanObserveNonUint32(use);
425 }
426
378 bool CanObserveNonInt32(MachineTypeUnion use) { 427 bool CanObserveNonInt32(MachineTypeUnion use) {
379 return (use & (kTypeUint32 | kTypeNumber | kTypeAny)) != 0; 428 return (use & (kTypeUint32 | kTypeNumber | kTypeAny)) != 0;
380 } 429 }
381 430
382 bool CanObserveMinusZero(MachineTypeUnion use) { 431 bool CanObserveMinusZero(MachineTypeUnion use) {
383 // TODO(turbofan): technically Uint32 cannot observe minus zero either. 432 // TODO(turbofan): technically Uint32 cannot observe minus zero either.
384 return (use & (kTypeUint32 | kTypeNumber | kTypeAny)) != 0; 433 return (use & (kTypeUint32 | kTypeNumber | kTypeAny)) != 0;
385 } 434 }
386 435
387 bool CanObserveNonUint32(MachineTypeUnion use) { 436 bool CanObserveNonUint32(MachineTypeUnion use) {
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
509 break; 558 break;
510 } 559 }
511 case IrOpcode::kNumberAdd: 560 case IrOpcode::kNumberAdd:
512 case IrOpcode::kNumberSubtract: { 561 case IrOpcode::kNumberSubtract: {
513 // Add and subtract reduce to Int32Add/Sub if the inputs 562 // Add and subtract reduce to Int32Add/Sub if the inputs
514 // are already integers and all uses are truncating. 563 // are already integers and all uses are truncating.
515 if (CanLowerToInt32Binop(node, use)) { 564 if (CanLowerToInt32Binop(node, use)) {
516 // => signed Int32Add/Sub 565 // => signed Int32Add/Sub
517 VisitInt32Binop(node); 566 VisitInt32Binop(node);
518 if (lower()) node->set_op(Int32Op(node)); 567 if (lower()) node->set_op(Int32Op(node));
568 } else if (CanLowerToInt32AdditiveBinop(node, use)) {
569 // => signed Int32Add/Sub, truncating inputs
570 ProcessTruncateWord32Input(node, 0, kTypeInt32);
571 ProcessTruncateWord32Input(node, 1, kTypeInt32);
572 SetOutput(node, kMachInt32);
573 if (lower()) node->set_op(Int32Op(node));
519 } else if (CanLowerToUint32Binop(node, use)) { 574 } else if (CanLowerToUint32Binop(node, use)) {
520 // => unsigned Int32Add/Sub 575 // => unsigned Int32Add/Sub
521 VisitUint32Binop(node); 576 VisitUint32Binop(node);
522 if (lower()) node->set_op(Uint32Op(node)); 577 if (lower()) node->set_op(Uint32Op(node));
578 } else if (CanLowerToUint32AdditiveBinop(node, use)) {
579 // => signed Int32Add/Sub, truncating inputs
580 ProcessTruncateWord32Input(node, 0, kTypeUint32);
581 ProcessTruncateWord32Input(node, 1, kTypeUint32);
582 SetOutput(node, kMachUint32);
583 if (lower()) node->set_op(Uint32Op(node));
523 } else { 584 } else {
524 // => Float64Add/Sub 585 // => Float64Add/Sub
525 VisitFloat64Binop(node); 586 VisitFloat64Binop(node);
526 if (lower()) node->set_op(Float64Op(node)); 587 if (lower()) node->set_op(Float64Op(node));
527 } 588 }
528 break; 589 break;
529 } 590 }
530 case IrOpcode::kNumberMultiply: { 591 case IrOpcode::kNumberMultiply: {
531 NumberMatcher right(node->InputAt(1)); 592 NumberMatcher right(node->InputAt(1));
532 if (right.IsInRange(-1048576, 1048576)) { // must fit double mantissa. 593 if (right.IsInRange(-1048576, 1048576)) { // must fit double mantissa.
(...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
908 private: 969 private:
909 JSGraph* jsgraph_; 970 JSGraph* jsgraph_;
910 int count_; // number of nodes in the graph 971 int count_; // number of nodes in the graph
911 NodeInfo* info_; // node id -> usage information 972 NodeInfo* info_; // node id -> usage information
912 NodeVector nodes_; // collected nodes 973 NodeVector nodes_; // collected nodes
913 NodeVector replacements_; // replacements to be done after lowering 974 NodeVector replacements_; // replacements to be done after lowering
914 bool contains_js_nodes_; // {true} if a JS operator was seen 975 bool contains_js_nodes_; // {true} if a JS operator was seen
915 Phase phase_; // current phase of algorithm 976 Phase phase_; // current phase of algorithm
916 RepresentationChanger* changer_; // for inserting representation changes 977 RepresentationChanger* changer_; // for inserting representation changes
917 ZoneQueue<Node*> queue_; // queue for traversing the graph 978 ZoneQueue<Node*> queue_; // queue for traversing the graph
979 Type* safe_int_additive_range_;
918 980
919 NodeInfo* GetInfo(Node* node) { 981 NodeInfo* GetInfo(Node* node) {
920 DCHECK(node->id() >= 0); 982 DCHECK(node->id() >= 0);
921 DCHECK(node->id() < count_); 983 DCHECK(node->id() < count_);
922 return &info_[node->id()]; 984 return &info_[node->id()];
923 } 985 }
924 986
925 MachineTypeUnion GetUseInfo(Node* node) { return GetInfo(node)->use; } 987 MachineTypeUnion GetUseInfo(Node* node) { return GetInfo(node)->use; }
926 }; 988 };
927 989
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after
1168 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { 1230 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) {
1169 node->set_op(machine()->IntLessThanOrEqual()); 1231 node->set_op(machine()->IntLessThanOrEqual());
1170 node->ReplaceInput(0, StringComparison(node, true)); 1232 node->ReplaceInput(0, StringComparison(node, true));
1171 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); 1233 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL));
1172 } 1234 }
1173 1235
1174 1236
1175 } // namespace compiler 1237 } // namespace compiler
1176 } // namespace internal 1238 } // namespace internal
1177 } // namespace v8 1239 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/representation-change.h ('k') | src/compiler/typer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698