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

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

Issue 620553008: Lower NumberMultiply, NumberDivide, and NumberModulus to Int32Mul, Int32[U]Div, and Int32[U]Mod whe… (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: git cl try 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 | « no previous file | test/cctest/compiler/test-simplified-lowering.cc » ('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 "src/base/bits.h" 7 #include "src/base/bits.h"
8 #include "src/code-factory.h" 8 #include "src/code-factory.h"
9 #include "src/compiler/common-operator.h" 9 #include "src/compiler/common-operator.h"
10 #include "src/compiler/graph-inl.h" 10 #include "src/compiler/graph-inl.h"
11 #include "src/compiler/node-matchers.h"
11 #include "src/compiler/node-properties-inl.h" 12 #include "src/compiler/node-properties-inl.h"
12 #include "src/compiler/representation-change.h" 13 #include "src/compiler/representation-change.h"
13 #include "src/compiler/simplified-lowering.h" 14 #include "src/compiler/simplified-lowering.h"
14 #include "src/compiler/simplified-operator.h" 15 #include "src/compiler/simplified-operator.h"
15 #include "src/objects.h" 16 #include "src/objects.h"
16 17
17 namespace v8 { 18 namespace v8 {
18 namespace internal { 19 namespace internal {
19 namespace compiler { 20 namespace compiler {
20 21
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after
347 } 348 }
348 349
349 const Operator* Uint32Op(Node* node) { 350 const Operator* Uint32Op(Node* node) {
350 return changer_->Uint32OperatorFor(node->opcode()); 351 return changer_->Uint32OperatorFor(node->opcode());
351 } 352 }
352 353
353 const Operator* Float64Op(Node* node) { 354 const Operator* Float64Op(Node* node) {
354 return changer_->Float64OperatorFor(node->opcode()); 355 return changer_->Float64OperatorFor(node->opcode());
355 } 356 }
356 357
358 bool CanLowerToInt32Binop(Node* node, MachineTypeUnion use) {
359 return BothInputsAre(node, Type::Signed32()) && !CanObserveNonInt32(use);
360 }
361
362 bool CanLowerToUint32Binop(Node* node, MachineTypeUnion use) {
363 return BothInputsAre(node, Type::Unsigned32()) && !CanObserveNonUint32(use);
364 }
365
366 bool CanObserveNonInt32(MachineTypeUnion use) {
367 return (use & (kTypeUint32 | kTypeNumber | kTypeAny)) != 0;
368 }
369
370 bool CanObserveMinusZero(MachineTypeUnion use) {
371 // TODO(turbofan): technically Uint32 cannot observe minus zero either.
372 return (use & (kTypeUint32 | kTypeNumber | kTypeAny)) != 0;
373 }
374
375 bool CanObserveNonUint32(MachineTypeUnion use) {
376 return (use & (kTypeInt32 | kTypeNumber | kTypeAny)) != 0;
377 }
378
357 // Dispatching routine for visiting the node {node} with the usage {use}. 379 // Dispatching routine for visiting the node {node} with the usage {use}.
358 // Depending on the operator, propagate new usage info to the inputs. 380 // Depending on the operator, propagate new usage info to the inputs.
359 void VisitNode(Node* node, MachineTypeUnion use, 381 void VisitNode(Node* node, MachineTypeUnion use,
360 SimplifiedLowering* lowering) { 382 SimplifiedLowering* lowering) {
361 switch (node->opcode()) { 383 switch (node->opcode()) {
362 //------------------------------------------------------------------ 384 //------------------------------------------------------------------
363 // Common operators. 385 // Common operators.
364 //------------------------------------------------------------------ 386 //------------------------------------------------------------------
365 case IrOpcode::kStart: 387 case IrOpcode::kStart:
366 case IrOpcode::kDead: 388 case IrOpcode::kDead:
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 // => Float64Cmp 493 // => Float64Cmp
472 VisitFloat64Cmp(node); 494 VisitFloat64Cmp(node);
473 if (lower()) node->set_op(Float64Op(node)); 495 if (lower()) node->set_op(Float64Op(node));
474 } 496 }
475 break; 497 break;
476 } 498 }
477 case IrOpcode::kNumberAdd: 499 case IrOpcode::kNumberAdd:
478 case IrOpcode::kNumberSubtract: { 500 case IrOpcode::kNumberSubtract: {
479 // Add and subtract reduce to Int32Add/Sub if the inputs 501 // Add and subtract reduce to Int32Add/Sub if the inputs
480 // are already integers and all uses are truncating. 502 // are already integers and all uses are truncating.
481 if (BothInputsAre(node, Type::Signed32()) && 503 if (CanLowerToInt32Binop(node, use)) {
482 (use & (kTypeUint32 | kTypeNumber | kTypeAny)) == 0) {
483 // => signed Int32Add/Sub 504 // => signed Int32Add/Sub
484 VisitInt32Binop(node); 505 VisitInt32Binop(node);
485 if (lower()) node->set_op(Int32Op(node)); 506 if (lower()) node->set_op(Int32Op(node));
486 } else if (BothInputsAre(node, Type::Unsigned32()) && 507 } else if (CanLowerToUint32Binop(node, use)) {
487 (use & (kTypeInt32 | kTypeNumber | kTypeAny)) == 0) {
488 // => unsigned Int32Add/Sub 508 // => unsigned Int32Add/Sub
489 VisitUint32Binop(node); 509 VisitUint32Binop(node);
490 if (lower()) node->set_op(Uint32Op(node)); 510 if (lower()) node->set_op(Uint32Op(node));
491 } else { 511 } else {
492 // => Float64Add/Sub 512 // => Float64Add/Sub
493 VisitFloat64Binop(node); 513 VisitFloat64Binop(node);
494 if (lower()) node->set_op(Float64Op(node)); 514 if (lower()) node->set_op(Float64Op(node));
495 } 515 }
496 break; 516 break;
497 } 517 }
498 case IrOpcode::kNumberMultiply: 518 case IrOpcode::kNumberMultiply: {
499 case IrOpcode::kNumberDivide: 519 NumberMatcher right(node->InputAt(1));
500 case IrOpcode::kNumberModulus: { 520 if (right.IsInRange(-1048576, 1048576)) { // must fit double mantissa.
501 // Float64Mul/Div/Mod 521 if (CanLowerToInt32Binop(node, use)) {
522 // => signed Int32Mul
523 VisitInt32Binop(node);
524 if (lower()) node->set_op(Int32Op(node));
525 break;
526 }
527 }
528 // => Float64Mul
502 VisitFloat64Binop(node); 529 VisitFloat64Binop(node);
503 if (lower()) node->set_op(Float64Op(node)); 530 if (lower()) node->set_op(Float64Op(node));
504 break; 531 break;
532 }
533 case IrOpcode::kNumberDivide: {
534 NumberMatcher right(node->InputAt(1));
535 if (right.HasValue() && !right.Is(0) && !right.Is(-1)) {
536 if (CanLowerToInt32Binop(node, use)) {
537 // => signed Int32Div
538 VisitInt32Binop(node);
539 if (lower()) node->set_op(Int32Op(node));
540 break;
541 } else if (CanLowerToUint32Binop(node, use)) {
542 // => unsigned Uint32Div
543 VisitUint32Binop(node);
544 if (lower()) node->set_op(Uint32Op(node));
545 break;
546 }
547 }
548 // => Float64Div
549 VisitFloat64Binop(node);
550 if (lower()) node->set_op(Float64Op(node));
551 break;
552 }
553 case IrOpcode::kNumberModulus: {
554 NumberMatcher right(node->InputAt(1));
555 if (right.HasValue() && !right.Is(0) && !right.Is(-1)) {
556 if (BothInputsAre(node, Type::Signed32()) &&
557 !CanObserveMinusZero(use)) {
558 // => signed Int32Mod
559 VisitInt32Binop(node);
560 if (lower()) node->set_op(Int32Op(node));
561 break;
562 } else if (BothInputsAre(node, Type::Unsigned32())) {
563 // => unsigned Uint32Mod
564 VisitUint32Binop(node);
565 if (lower()) node->set_op(Uint32Op(node));
566 break;
567 }
568 }
569 // => Float64Mod
570 VisitFloat64Binop(node);
571 if (lower()) node->set_op(Float64Op(node));
572 break;
505 } 573 }
506 case IrOpcode::kNumberToInt32: { 574 case IrOpcode::kNumberToInt32: {
507 MachineTypeUnion use_rep = use & kRepMask; 575 MachineTypeUnion use_rep = use & kRepMask;
508 Node* input = node->InputAt(0); 576 Node* input = node->InputAt(0);
509 MachineTypeUnion in = GetInfo(input)->output; 577 MachineTypeUnion in = GetInfo(input)->output;
510 if (NodeProperties::GetBounds(input).upper->Is(Type::Signed32()) || 578 if (NodeProperties::GetBounds(input).upper->Is(Type::Signed32())) {
511 (in & kTypeMask) == kTypeInt32 || (in & kRepMask) == kRepWord32) { 579 // If the input has type int32, pass through representation.
512 // If the input has type int32, or is already a word32, just change
513 // representation if necessary.
514 VisitUnop(node, kTypeInt32 | use_rep, kTypeInt32 | use_rep); 580 VisitUnop(node, kTypeInt32 | use_rep, kTypeInt32 | use_rep);
515 if (lower()) DeferReplacement(node, node->InputAt(0)); 581 if (lower()) DeferReplacement(node, node->InputAt(0));
582 } else if ((in & kTypeMask) == kTypeUint32 ||
583 (in & kTypeMask) == kTypeInt32 ||
584 (in & kRepMask) == kRepWord32) {
585 // Just change representation if necessary.
586 VisitUnop(node, kTypeInt32 | kRepWord32, kTypeInt32 | kRepWord32);
587 if (lower()) DeferReplacement(node, node->InputAt(0));
516 } else { 588 } else {
517 // Require the input in float64 format and perform truncation. 589 // Require the input in float64 format and perform truncation.
518 // TODO(turbofan): avoid a truncation with a smi check. 590 // TODO(turbofan): avoid a truncation with a smi check.
519 VisitUnop(node, kTypeInt32 | kRepFloat64, kTypeInt32 | kRepWord32); 591 VisitUnop(node, kTypeInt32 | kRepFloat64, kTypeInt32 | kRepWord32);
520 if (lower()) 592 if (lower())
521 node->set_op(lowering->machine()->TruncateFloat64ToInt32()); 593 node->set_op(lowering->machine()->TruncateFloat64ToInt32());
522 } 594 }
523 break; 595 break;
524 } 596 }
525 case IrOpcode::kNumberToUint32: { 597 case IrOpcode::kNumberToUint32: {
526 MachineTypeUnion use_rep = use & kRepMask; 598 MachineTypeUnion use_rep = use & kRepMask;
527 Node* input = node->InputAt(0); 599 Node* input = node->InputAt(0);
528 MachineTypeUnion in = GetInfo(input)->output; 600 MachineTypeUnion in = GetInfo(input)->output;
529 if (NodeProperties::GetBounds(input).upper->Is(Type::Unsigned32()) || 601 if (NodeProperties::GetBounds(input).upper->Is(Type::Unsigned32())) {
530 (in & kTypeMask) == kTypeUint32) { 602 // If the input has type uint32, pass through representation.
531 // If the input has type uint32, just change representation.
532 VisitUnop(node, kTypeUint32 | use_rep, kTypeUint32 | use_rep); 603 VisitUnop(node, kTypeUint32 | use_rep, kTypeUint32 | use_rep);
533 if (lower()) DeferReplacement(node, node->InputAt(0)); 604 if (lower()) DeferReplacement(node, node->InputAt(0));
605 } else if ((in & kTypeMask) == kTypeUint32 ||
606 (in & kTypeMask) == kTypeInt32 ||
607 (in & kRepMask) == kRepWord32) {
608 // Just change representation if necessary.
609 VisitUnop(node, kTypeUint32 | kRepWord32, kTypeUint32 | kRepWord32);
610 if (lower()) DeferReplacement(node, node->InputAt(0));
534 } else { 611 } else {
535 // Require the input in float64 format and perform truncation. 612 // Require the input in float64 format and perform truncation.
536 // TODO(turbofan): avoid a truncation with a smi check. 613 // TODO(turbofan): avoid a truncation with a smi check.
537 VisitUnop(node, kTypeUint32 | kRepFloat64, kTypeUint32 | kRepWord32); 614 VisitUnop(node, kTypeUint32 | kRepFloat64, kTypeUint32 | kRepWord32);
538 if (lower()) 615 if (lower())
539 node->set_op(lowering->machine()->TruncateFloat64ToInt32()); 616 node->set_op(lowering->machine()->TruncateFloat64ToInt32());
540 } 617 }
541 break; 618 break;
542 } 619 }
543 case IrOpcode::kReferenceEqual: { 620 case IrOpcode::kReferenceEqual: {
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after
737 } 814 }
738 SetOutput(node, kMachAnyTagged); 815 SetOutput(node, kMachAnyTagged);
739 break; 816 break;
740 default: 817 default:
741 VisitInputs(node); 818 VisitInputs(node);
742 break; 819 break;
743 } 820 }
744 } 821 }
745 822
746 void DeferReplacement(Node* node, Node* replacement) { 823 void DeferReplacement(Node* node, Node* replacement) {
824 if (FLAG_trace_representation) {
825 TRACE(("defer replacement #%d:%s with #%d:%s\n", node->id(),
826 node->op()->mnemonic(), replacement->id(),
827 replacement->op()->mnemonic()));
828 }
747 if (replacement->id() < count_) { 829 if (replacement->id() < count_) {
748 // Replace with a previously existing node eagerly. 830 // Replace with a previously existing node eagerly.
749 node->ReplaceUses(replacement); 831 node->ReplaceUses(replacement);
750 } else { 832 } else {
751 // Otherwise, we are replacing a node with a representation change. 833 // Otherwise, we are replacing a node with a representation change.
752 // Such a substitution must be done after all lowering is done, because 834 // Such a substitution must be done after all lowering is done, because
753 // new nodes do not have {NodeInfo} entries, and that would confuse 835 // new nodes do not have {NodeInfo} entries, and that would confuse
754 // the representation change insertion for uses of it. 836 // the representation change insertion for uses of it.
755 replacements_.push_back(node); 837 replacements_.push_back(node);
756 replacements_.push_back(replacement); 838 replacements_.push_back(replacement);
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
973 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) { 1055 void SimplifiedLowering::DoStringLessThanOrEqual(Node* node) {
974 node->set_op(machine()->IntLessThanOrEqual()); 1056 node->set_op(machine()->IntLessThanOrEqual());
975 node->ReplaceInput(0, StringComparison(node, true)); 1057 node->ReplaceInput(0, StringComparison(node, true));
976 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL)); 1058 node->ReplaceInput(1, jsgraph()->SmiConstant(EQUAL));
977 } 1059 }
978 1060
979 1061
980 } // namespace compiler 1062 } // namespace compiler
981 } // namespace internal 1063 } // namespace internal
982 } // namespace v8 1064 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/cctest/compiler/test-simplified-lowering.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698