Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |