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

Side by Side Diff: runtime/vm/flow_graph_optimizer.cc

Issue 11369158: Reland: Improve smi shift operations and avoid repeated deoptimizations. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month 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
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/flow_graph_optimizer.h" 5 #include "vm/flow_graph_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/cha.h" 8 #include "vm/cha.h"
9 #include "vm/flow_graph_builder.h" 9 #include "vm/flow_graph_builder.h"
10 #include "vm/flow_graph_compiler.h" 10 #include "vm/flow_graph_compiler.h"
(...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 674
675 bool FlowGraphOptimizer::TryReplaceWithBinaryOp(InstanceCallInstr* call, 675 bool FlowGraphOptimizer::TryReplaceWithBinaryOp(InstanceCallInstr* call,
676 Token::Kind op_kind) { 676 Token::Kind op_kind) {
677 intptr_t operands_type = kIllegalCid; 677 intptr_t operands_type = kIllegalCid;
678 ASSERT(call->HasICData()); 678 ASSERT(call->HasICData());
679 const ICData& ic_data = *call->ic_data(); 679 const ICData& ic_data = *call->ic_data();
680 switch (op_kind) { 680 switch (op_kind) {
681 case Token::kADD: 681 case Token::kADD:
682 case Token::kSUB: 682 case Token::kSUB:
683 if (HasOnlyTwoSmis(ic_data)) { 683 if (HasOnlyTwoSmis(ic_data)) {
684 operands_type = kSmiCid; 684 // Don't generate smi code if the IC data is marked because
685 // of an overflow.
686 operands_type = (ic_data.deopt_reason() == kDeoptBinarySmiOp)
687 ? kMintCid
688 : kSmiCid;
685 } else if (HasTwoMintOrSmi(ic_data) && 689 } else if (HasTwoMintOrSmi(ic_data) &&
686 FlowGraphCompiler::SupportsUnboxedMints()) { 690 FlowGraphCompiler::SupportsUnboxedMints()) {
691 // Don't generate mint code if the IC data is marked because of an
692 // overflow.
693 if (ic_data.deopt_reason() == kDeoptBinaryMintOp) return false;
687 operands_type = kMintCid; 694 operands_type = kMintCid;
688 } else if (ShouldSpecializeForDouble(ic_data)) { 695 } else if (ShouldSpecializeForDouble(ic_data)) {
689 operands_type = kDoubleCid; 696 operands_type = kDoubleCid;
690 } else { 697 } else {
691 return false; 698 return false;
692 } 699 }
693 break; 700 break;
694 case Token::kMUL: 701 case Token::kMUL:
695 if (HasOnlyTwoSmis(ic_data)) { 702 if (HasOnlyTwoSmis(ic_data)) {
703 // Don't generate smi code if the IC data is marked because of an
704 // overflow.
705 // TODO(fschneider): Add unboxed mint multiplication.
706 if (ic_data.deopt_reason() == kDeoptBinarySmiOp) return false;
696 operands_type = kSmiCid; 707 operands_type = kSmiCid;
697 } else if (ShouldSpecializeForDouble(ic_data)) { 708 } else if (ShouldSpecializeForDouble(ic_data)) {
698 operands_type = kDoubleCid; 709 operands_type = kDoubleCid;
699 } else { 710 } else {
700 return false; 711 return false;
701 } 712 }
702 break; 713 break;
703 case Token::kDIV: 714 case Token::kDIV:
704 if (ShouldSpecializeForDouble(ic_data)) { 715 if (ShouldSpecializeForDouble(ic_data)) {
705 operands_type = kDoubleCid; 716 operands_type = kDoubleCid;
706 } else { 717 } else {
707 return false; 718 return false;
708 } 719 }
709 break; 720 break;
710 case Token::kMOD: 721 case Token::kMOD:
711 if (HasOnlyTwoSmis(ic_data)) { 722 if (HasOnlyTwoSmis(ic_data)) {
712 operands_type = kSmiCid; 723 operands_type = kSmiCid;
713 } else { 724 } else {
714 return false; 725 return false;
715 } 726 }
716 break; 727 break;
717 case Token::kBIT_AND: 728 case Token::kBIT_AND:
718 case Token::kBIT_OR: 729 case Token::kBIT_OR:
719 case Token::kBIT_XOR: 730 case Token::kBIT_XOR:
720 if (HasOnlyTwoSmis(ic_data)) { 731 if (HasOnlyTwoSmis(ic_data)) {
721 operands_type = kSmiCid; 732 operands_type = kSmiCid;
722 } else if (HasTwoMintOrSmi(ic_data) && 733 } else if (HasTwoMintOrSmi(ic_data)) {
723 FlowGraphCompiler::SupportsUnboxedMints()) {
724 operands_type = kMintCid; 734 operands_type = kMintCid;
725 } else { 735 } else {
726 return false; 736 return false;
727 } 737 }
728 break; 738 break;
729 case Token::kSHR: 739 case Token::kSHR:
730 case Token::kSHL: 740 case Token::kSHL:
731 if (HasOnlyTwoSmis(ic_data)) { 741 if (HasOnlyTwoSmis(ic_data)) {
732 operands_type = kSmiCid; 742 // Left shift may overflow from smi into mint or big ints.
733 } else if (FlowGraphCompiler::SupportsUnboxedMints() && 743 // Don't generate smi code if the IC data is marked because
734 HasTwoMintOrSmi(ic_data) && 744 // of an overflow.
745 if (ic_data.deopt_reason() == kDeoptShiftMintOp) return false;
746 operands_type = (ic_data.deopt_reason() == kDeoptBinarySmiOp)
747 ? kMintCid
748 : kSmiCid;
749 } else if (HasTwoMintOrSmi(ic_data) &&
735 HasOnlyOneSmi(ICData::Handle( 750 HasOnlyOneSmi(ICData::Handle(
736 ic_data.AsUnaryClassChecksForArgNr(1)))) { 751 ic_data.AsUnaryClassChecksForArgNr(1)))) {
752 // Don't generate mint code if the IC data is marked because of an
753 // overflow.
754 if (ic_data.deopt_reason() == kDeoptShiftMintOp) return false;
737 // Check for smi/mint << smi or smi/mint >> smi. 755 // Check for smi/mint << smi or smi/mint >> smi.
738 operands_type = kMintCid; 756 operands_type = kMintCid;
739 } else { 757 } else {
740 return false; 758 return false;
741 } 759 }
742 break; 760 break;
743 case Token::kTRUNCDIV: 761 case Token::kTRUNCDIV:
744 if (HasOnlyTwoSmis(ic_data)) { 762 if (HasOnlyTwoSmis(ic_data)) {
763 if (ic_data.deopt_reason() == kDeoptBinarySmiOp) return false;
745 operands_type = kSmiCid; 764 operands_type = kSmiCid;
746 } else { 765 } else {
747 return false; 766 return false;
748 } 767 }
749 break; 768 break;
750 default: 769 default:
751 UNREACHABLE(); 770 UNREACHABLE();
752 }; 771 };
753 772
754 ASSERT(call->ArgumentCount() == 2); 773 ASSERT(call->ArgumentCount() == 2);
755 if (operands_type == kDoubleCid) { 774 if (operands_type == kDoubleCid) {
756 Value* left = call->ArgumentAt(0)->value(); 775 Value* left = call->ArgumentAt(0)->value();
757 Value* right = call->ArgumentAt(1)->value(); 776 Value* right = call->ArgumentAt(1)->value();
758 777
759 // Check that either left or right are not a smi. Result or a 778 // Check that either left or right are not a smi. Result or a
760 // binary operation with two smis is a smi not a double. 779 // binary operation with two smis is a smi not a double.
761 InsertBefore(call, 780 InsertBefore(call,
762 new CheckEitherNonSmiInstr(left->Copy(), 781 new CheckEitherNonSmiInstr(left->Copy(),
763 right->Copy(), 782 right->Copy(),
764 call), 783 call),
765 call->env(), 784 call->env(),
766 Definition::kEffect); 785 Definition::kEffect);
767 786
768 BinaryDoubleOpInstr* double_bin_op = 787 BinaryDoubleOpInstr* double_bin_op =
769 new BinaryDoubleOpInstr(op_kind, left->Copy(), right->Copy(), call); 788 new BinaryDoubleOpInstr(op_kind, left->Copy(), right->Copy(), call);
770 call->ReplaceWith(double_bin_op, current_iterator()); 789 call->ReplaceWith(double_bin_op, current_iterator());
771 RemovePushArguments(call); 790 RemovePushArguments(call);
772 } else if (operands_type == kMintCid) { 791 } else if (operands_type == kMintCid) {
792 if (!FlowGraphCompiler::SupportsUnboxedMints()) return false;
773 Value* left = call->ArgumentAt(0)->value(); 793 Value* left = call->ArgumentAt(0)->value();
774 Value* right = call->ArgumentAt(1)->value(); 794 Value* right = call->ArgumentAt(1)->value();
775 if ((op_kind == Token::kSHR) || (op_kind == Token::kSHL)) { 795 if ((op_kind == Token::kSHR) || (op_kind == Token::kSHL)) {
776 ShiftMintOpInstr* shift_op = 796 ShiftMintOpInstr* shift_op =
777 new ShiftMintOpInstr(op_kind, left, right, call); 797 new ShiftMintOpInstr(op_kind, left, right, call);
778 call->ReplaceWith(shift_op, current_iterator()); 798 call->ReplaceWith(shift_op, current_iterator());
779 } else { 799 } else {
780 BinaryMintOpInstr* bin_op = 800 BinaryMintOpInstr* bin_op =
781 new BinaryMintOpInstr(op_kind, left, right, call); 801 new BinaryMintOpInstr(op_kind, left, right, call);
782 call->ReplaceWith(bin_op, current_iterator()); 802 call->ReplaceWith(bin_op, current_iterator());
(...skipping 2930 matching lines...) Expand 10 before | Expand all | Expand 10 after
3713 3733
3714 if (FLAG_trace_constant_propagation) { 3734 if (FLAG_trace_constant_propagation) {
3715 OS::Print("\n==== After constant propagation ====\n"); 3735 OS::Print("\n==== After constant propagation ====\n");
3716 FlowGraphPrinter printer(*graph_); 3736 FlowGraphPrinter printer(*graph_);
3717 printer.PrintBlocks(); 3737 printer.PrintBlocks();
3718 } 3738 }
3719 } 3739 }
3720 3740
3721 3741
3722 } // namespace dart 3742 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698