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

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

Issue 10827387: Reenable elimination of strict equals when right side is true. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 4 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
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/intermediate_language.h" 5 #include "vm/intermediate_language.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/dart_entry.h" 8 #include "vm/dart_entry.h"
9 #include "vm/flow_graph_allocator.h" 9 #include "vm/flow_graph_allocator.h"
10 #include "vm/flow_graph_builder.h" 10 #include "vm/flow_graph_builder.h"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
52 return false; 52 return false;
53 } 53 }
54 ConstantVal* constant = bind->computation()->AsConstant(); 54 ConstantVal* constant = bind->computation()->AsConstant();
55 if (constant != NULL) { 55 if (constant != NULL) {
56 return constant->value().IsNull(); 56 return constant->value().IsNull();
57 } 57 }
58 return false; 58 return false;
59 } 59 }
60 60
61 61
62 const Object& UseVal::BoundConstant() const {
63 ASSERT(BindsToConstant());
64 BindInstr* bind = definition()->AsBind();
65 ASSERT(bind != NULL);
66 ConstantVal* constant = bind->computation()->AsConstant();
67 ASSERT(constant != NULL);
68 return constant->value();
69 }
70
71
62 void UseVal::RemoveFromUseList() { 72 void UseVal::RemoveFromUseList() {
63 ASSERT(definition_ != NULL); 73 ASSERT(definition_ != NULL);
64 if (next_use_ != NULL) { 74 if (next_use_ != NULL) {
65 next_use_->previous_use_ = previous_use_; 75 next_use_->previous_use_ = previous_use_;
66 } 76 }
67 if (previous_use_ != NULL) { 77 if (previous_use_ != NULL) {
68 previous_use_->next_use_ = next_use_; 78 previous_use_->next_use_ = next_use_;
69 } else { 79 } else {
70 // This is the head of the list. 80 // This is the head of the list.
71 ASSERT(definition_->use_list() == this); 81 ASSERT(definition_->use_list() == this);
(...skipping 657 matching lines...) Expand 10 before | Expand all | Expand 10 after
729 (receiver_class_id() == kNumberCid)) { 739 (receiver_class_id() == kNumberCid)) {
730 return Type::BoolInterface(); 740 return Type::BoolInterface();
731 } 741 }
732 if (HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid)) { 742 if (HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid)) {
733 return Type::BoolInterface(); 743 return Type::BoolInterface();
734 } 744 }
735 return Type::DynamicType(); 745 return Type::DynamicType();
736 } 746 }
737 747
738 748
749 intptr_t EqualityCompareComp::ResultCid() const {
750 if ((receiver_class_id() == kSmiCid) ||
751 (receiver_class_id() == kDoubleCid) ||
752 (receiver_class_id() == kNumberCid)) {
753 // Known/library equalities that are guaranteed to return Boolean.
754 return kBoolCid;
755 }
756 if (HasICData() && ic_data()->AllTargetsHaveSameOwner(kInstanceCid)) {
757 return kBoolCid;
758 }
759 return kDynamicCid;
760 }
761
762
739 RawAbstractType* RelationalOpComp::CompileType() const { 763 RawAbstractType* RelationalOpComp::CompileType() const {
740 if ((operands_class_id() == kSmiCid) || 764 if ((operands_class_id() == kSmiCid) ||
741 (operands_class_id() == kDoubleCid) || 765 (operands_class_id() == kDoubleCid) ||
742 (operands_class_id() == kNumberCid)) { 766 (operands_class_id() == kNumberCid)) {
767 // Known/library relational ops that are guaranteed to return Boolean.
743 return Type::BoolInterface(); 768 return Type::BoolInterface();
744 } 769 }
745 return Type::DynamicType(); 770 return Type::DynamicType();
746 } 771 }
747 772
748 773
774 intptr_t RelationalOpComp::ResultCid() const {
775 if ((operands_class_id() == kSmiCid) ||
776 (operands_class_id() == kDoubleCid) ||
777 (operands_class_id() == kNumberCid)) {
778 // Known/library relational ops that are guaranteed to return Boolean.
779 return kBoolCid;
780 }
781 return kDynamicCid;
782 }
783
784
749 RawAbstractType* NativeCallComp::CompileType() const { 785 RawAbstractType* NativeCallComp::CompileType() const {
750 // The result type of the native function is identical to the result type of 786 // The result type of the native function is identical to the result type of
751 // the enclosing native Dart function. However, we prefer to check the type 787 // the enclosing native Dart function. However, we prefer to check the type
752 // of the value returned from the native call. 788 // of the value returned from the native call.
753 return Type::DynamicType(); 789 return Type::DynamicType();
754 } 790 }
755 791
756 792
757 RawAbstractType* LoadIndexedComp::CompileType() const { 793 RawAbstractType* LoadIndexedComp::CompileType() const {
758 return Type::DynamicType(); 794 return Type::DynamicType();
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
870 return AbstractType::null(); 906 return AbstractType::null();
871 } 907 }
872 908
873 909
874 RawAbstractType* CheckStackOverflowComp::CompileType() const { 910 RawAbstractType* CheckStackOverflowComp::CompileType() const {
875 return AbstractType::null(); 911 return AbstractType::null();
876 } 912 }
877 913
878 914
879 RawAbstractType* BinaryOpComp::CompileType() const { 915 RawAbstractType* BinaryOpComp::CompileType() const {
880 // TODO(srdjan): Convert to use with class-ids instead of types. 916 ObjectStore* object_store = Isolate::Current()->object_store();
881 if (operands_type() == kMintOperands) { 917 if (operands_type() == kMintOperands) {
882 return Isolate::Current()->object_store()->mint_type(); 918 return object_store->mint_type();
883 } else if (op_kind() == Token::kSHL) { 919 }
920 if (op_kind() == Token::kSHL) {
884 return Type::IntInterface(); 921 return Type::IntInterface();
885 } else {
886 ASSERT(operands_type() == kSmiOperands);
887 return Isolate::Current()->object_store()->smi_type();
888 } 922 }
923 ASSERT(operands_type() == kSmiOperands);
924 return object_store->smi_type();
925 }
926
927
928 intptr_t BinaryOpComp::ResultCid() const {
929 if (operands_type() == kMintOperands) {
930 return kMintCid;
931 }
932 ASSERT(operands_type() == kSmiOperands);
933 return (op_kind() == Token::kSHL) ? kDynamicCid : kSmiCid;
889 } 934 }
890 935
891 936
892 RawAbstractType* DoubleBinaryOpComp::CompileType() const { 937 RawAbstractType* DoubleBinaryOpComp::CompileType() const {
893 return Type::DoubleInterface(); 938 return Type::DoubleInterface();
894 } 939 }
895 940
896 941
942 intptr_t DoubleBinaryOpComp::ResultCid() const {
943 return kDoubleCid;
944 }
945
946
897 RawAbstractType* UnarySmiOpComp::CompileType() const { 947 RawAbstractType* UnarySmiOpComp::CompileType() const {
898 return Type::IntInterface(); 948 return Type::IntInterface();
899 } 949 }
900 950
901 951
902 RawAbstractType* NumberNegateComp::CompileType() const { 952 RawAbstractType* NumberNegateComp::CompileType() const {
903 return Type::NumberInterface(); 953 return Type::DoubleInterface();
regis 2012/08/16 21:43:52 Why?
srdjan 2012/08/16 22:11:06 Adding comment: Implemented only for doubles. Add
904 } 954 }
905 955
906 956
907 RawAbstractType* DoubleToDoubleComp::CompileType() const { 957 RawAbstractType* DoubleToDoubleComp::CompileType() const {
908 return Type::DoubleInterface(); 958 return Type::DoubleInterface();
909 } 959 }
910 960
911 961
912 RawAbstractType* SmiToDoubleComp::CompileType() const { 962 RawAbstractType* SmiToDoubleComp::CompileType() const {
913 return Type::DoubleInterface(); 963 return Type::DoubleInterface();
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after
1111 } 1161 }
1112 1162
1113 1163
1114 void StoreContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { 1164 void StoreContextComp::EmitNativeCode(FlowGraphCompiler* compiler) {
1115 // Nothing to do. Context register were loaded by register allocator. 1165 // Nothing to do. Context register were loaded by register allocator.
1116 ASSERT(locs()->in(0).reg() == CTX); 1166 ASSERT(locs()->in(0).reg() == CTX);
1117 } 1167 }
1118 1168
1119 1169
1120 Definition* StrictCompareComp::TryReplace(BindInstr* instr) { 1170 Definition* StrictCompareComp::TryReplace(BindInstr* instr) {
1121 // TODO(srdjan): Do not use CompileType for class check elimination.
1122 return NULL;
1123 UseVal* left_use = left()->AsUse(); 1171 UseVal* left_use = left()->AsUse();
1124 UseVal* right_use = right()->AsUse(); 1172 UseVal* right_use = right()->AsUse();
1125 if ((right_use == NULL) || (left_use == NULL)) return NULL; 1173 if ((right_use == NULL) || (left_use == NULL)) return NULL;
1174 if (!right_use->BindsToConstant()) return NULL;
1175 const Object& right_constant = right_use->BoundConstant();
1126 Definition* left = left_use->definition(); 1176 Definition* left = left_use->definition();
1127 BindInstr* right = right_use->definition()->AsBind();
1128 if (right == NULL) return NULL;
1129 ConstantVal* right_constant = right->computation()->AsConstant();
1130 if (right_constant == NULL) return NULL;
1131 // TODO(fschneider): Handle other cases: e === false and e !== true/false. 1177 // TODO(fschneider): Handle other cases: e === false and e !== true/false.
1132 // Handles e === true. 1178 // Handles e === true.
1133 if ((kind() == Token::kEQ_STRICT) && 1179 if ((kind() == Token::kEQ_STRICT) &&
1134 (right_constant->value().raw() == Bool::True()) && 1180 (right_constant.raw() == Bool::True()) &&
1135 left_use->CompileTypeIsMoreSpecificThan( 1181 (left_use->ResultCid() == kBoolCid)) {
1136 Type::Handle(Type::BoolInterface()))) {
1137 // Remove the constant from the graph. 1182 // Remove the constant from the graph.
1138 right->RemoveFromGraph(); 1183 BindInstr* right = right_use->definition()->AsBind();
1184 if (right != NULL) {
1185 right->set_use_list(NULL);
1186 right->RemoveFromGraph();
1187 }
1139 // Return left subexpression as the replacement for this instruction. 1188 // Return left subexpression as the replacement for this instruction.
1140 return left; 1189 return left;
1141 } 1190 }
1142 return NULL; 1191 return NULL;
1143 } 1192 }
1144 1193
1145 1194
1146 LocationSummary* StrictCompareComp::MakeLocationSummary() const { 1195 LocationSummary* StrictCompareComp::MakeLocationSummary() const {
1147 return LocationSummary::Make(2, 1196 return LocationSummary::Make(2,
1148 Location::SameAsFirstInput(), 1197 Location::SameAsFirstInput(),
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after
1385 if (compiler->is_ssa()) { 1434 if (compiler->is_ssa()) {
1386 ASSERT(locs()->in(0).IsRegister()); 1435 ASSERT(locs()->in(0).IsRegister());
1387 __ PushRegister(locs()->in(0).reg()); 1436 __ PushRegister(locs()->in(0).reg());
1388 } 1437 }
1389 } 1438 }
1390 1439
1391 1440
1392 #undef __ 1441 #undef __
1393 1442
1394 } // namespace dart 1443 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698