| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/cpu.h" | 9 #include "vm/cpu.h" |
| 10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
| (...skipping 3700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3711 if (prev.IsNull()) { | 3711 if (prev.IsNull()) { |
| 3712 prev = Bool::Get(is_subtype).raw(); | 3712 prev = Bool::Get(is_subtype).raw(); |
| 3713 } else { | 3713 } else { |
| 3714 if (is_subtype != prev.value()) return Bool::null(); | 3714 if (is_subtype != prev.value()) return Bool::null(); |
| 3715 } | 3715 } |
| 3716 } | 3716 } |
| 3717 return prev.raw(); | 3717 return prev.raw(); |
| 3718 } | 3718 } |
| 3719 | 3719 |
| 3720 | 3720 |
| 3721 static Definition* OriginalDefinition(Definition* defn) { | |
| 3722 while (defn->IsRedefinition() || defn->IsAssertAssignable()) { | |
| 3723 if (defn->IsRedefinition()) { | |
| 3724 defn = defn->AsRedefinition()->value()->definition(); | |
| 3725 } else { | |
| 3726 defn = defn->AsAssertAssignable()->value()->definition(); | |
| 3727 } | |
| 3728 } | |
| 3729 return defn; | |
| 3730 } | |
| 3731 | |
| 3732 | |
| 3733 // Returns true if checking against this type is a direct class id comparison. | 3721 // Returns true if checking against this type is a direct class id comparison. |
| 3734 static bool TypeCheckAsClassEquality(const AbstractType& type) { | 3722 static bool TypeCheckAsClassEquality(const AbstractType& type) { |
| 3735 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded()); | 3723 ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded()); |
| 3736 // Requires CHA. | 3724 // Requires CHA. |
| 3737 if (!FLAG_use_cha) return false; | 3725 if (!FLAG_use_cha) return false; |
| 3738 if (!type.IsInstantiated()) return false; | 3726 if (!type.IsInstantiated()) return false; |
| 3739 const Class& type_class = Class::Handle(type.type_class()); | 3727 const Class& type_class = Class::Handle(type.type_class()); |
| 3740 // Signature classes have different type checking rules. | 3728 // Signature classes have different type checking rules. |
| 3741 if (type_class.IsSignatureClass()) return false; | 3729 if (type_class.IsSignatureClass()) return false; |
| 3742 // Could be an interface check? | 3730 // Could be an interface check? |
| (...skipping 18 matching lines...) Expand all Loading... |
| 3761 | 3749 |
| 3762 // TODO(srdjan): Use ICData to check if always true or false. | 3750 // TODO(srdjan): Use ICData to check if always true or false. |
| 3763 void FlowGraphOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) { | 3751 void FlowGraphOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) { |
| 3764 ASSERT(Token::IsTypeTestOperator(call->token_kind())); | 3752 ASSERT(Token::IsTypeTestOperator(call->token_kind())); |
| 3765 Definition* left = call->ArgumentAt(0); | 3753 Definition* left = call->ArgumentAt(0); |
| 3766 Definition* instantiator = call->ArgumentAt(1); | 3754 Definition* instantiator = call->ArgumentAt(1); |
| 3767 Definition* type_args = call->ArgumentAt(2); | 3755 Definition* type_args = call->ArgumentAt(2); |
| 3768 const AbstractType& type = | 3756 const AbstractType& type = |
| 3769 AbstractType::Cast(call->ArgumentAt(3)->AsConstant()->value()); | 3757 AbstractType::Cast(call->ArgumentAt(3)->AsConstant()->value()); |
| 3770 const bool negate = Bool::Cast( | 3758 const bool negate = Bool::Cast( |
| 3771 OriginalDefinition(call->ArgumentAt(4))->AsConstant()->value()).value(); | 3759 call->ArgumentAt(4)->OriginalDefinition()->AsConstant()->value()).value(); |
| 3772 const ICData& unary_checks = | 3760 const ICData& unary_checks = |
| 3773 ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecks()); | 3761 ICData::ZoneHandle(call->ic_data()->AsUnaryClassChecks()); |
| 3774 if (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) { | 3762 if (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) { |
| 3775 Bool& as_bool = Bool::ZoneHandle(InstanceOfAsBool(unary_checks, type)); | 3763 Bool& as_bool = Bool::ZoneHandle(InstanceOfAsBool(unary_checks, type)); |
| 3776 if (!as_bool.IsNull()) { | 3764 if (!as_bool.IsNull()) { |
| 3777 AddReceiverCheck(call); | 3765 AddReceiverCheck(call); |
| 3778 if (negate) { | 3766 if (negate) { |
| 3779 as_bool = Bool::Get(!as_bool.value()).raw(); | 3767 as_bool = Bool::Get(!as_bool.value()).raw(); |
| 3780 } | 3768 } |
| 3781 ConstantInstr* bool_const = flow_graph()->GetConstant(as_bool); | 3769 ConstantInstr* bool_const = flow_graph()->GetConstant(as_bool); |
| (...skipping 1386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5168 Place(Instruction* instr, bool* is_load) | 5156 Place(Instruction* instr, bool* is_load) |
| 5169 : kind_(kNone), | 5157 : kind_(kNone), |
| 5170 representation_(kNoRepresentation), | 5158 representation_(kNoRepresentation), |
| 5171 instance_(NULL), | 5159 instance_(NULL), |
| 5172 raw_selector_(0), | 5160 raw_selector_(0), |
| 5173 id_(0) { | 5161 id_(0) { |
| 5174 switch (instr->tag()) { | 5162 switch (instr->tag()) { |
| 5175 case Instruction::kLoadField: { | 5163 case Instruction::kLoadField: { |
| 5176 LoadFieldInstr* load_field = instr->AsLoadField(); | 5164 LoadFieldInstr* load_field = instr->AsLoadField(); |
| 5177 representation_ = load_field->representation(); | 5165 representation_ = load_field->representation(); |
| 5178 instance_ = OriginalDefinition(load_field->instance()->definition()); | 5166 instance_ = load_field->instance()->definition()->OriginalDefinition(); |
| 5179 if (load_field->field() != NULL) { | 5167 if (load_field->field() != NULL) { |
| 5180 kind_ = kField; | 5168 kind_ = kField; |
| 5181 field_ = load_field->field(); | 5169 field_ = load_field->field(); |
| 5182 } else { | 5170 } else { |
| 5183 kind_ = kVMField; | 5171 kind_ = kVMField; |
| 5184 offset_in_bytes_ = load_field->offset_in_bytes(); | 5172 offset_in_bytes_ = load_field->offset_in_bytes(); |
| 5185 } | 5173 } |
| 5186 *is_load = true; | 5174 *is_load = true; |
| 5187 break; | 5175 break; |
| 5188 } | 5176 } |
| 5189 | 5177 |
| 5190 case Instruction::kStoreInstanceField: { | 5178 case Instruction::kStoreInstanceField: { |
| 5191 StoreInstanceFieldInstr* store = | 5179 StoreInstanceFieldInstr* store = |
| 5192 instr->AsStoreInstanceField(); | 5180 instr->AsStoreInstanceField(); |
| 5193 representation_ = store->RequiredInputRepresentation( | 5181 representation_ = store->RequiredInputRepresentation( |
| 5194 StoreInstanceFieldInstr::kValuePos); | 5182 StoreInstanceFieldInstr::kValuePos); |
| 5195 instance_ = OriginalDefinition(store->instance()->definition()); | 5183 instance_ = store->instance()->definition()->OriginalDefinition(); |
| 5196 if (!store->field().IsNull()) { | 5184 if (!store->field().IsNull()) { |
| 5197 kind_ = kField; | 5185 kind_ = kField; |
| 5198 field_ = &store->field(); | 5186 field_ = &store->field(); |
| 5199 } else { | 5187 } else { |
| 5200 kind_ = kVMField; | 5188 kind_ = kVMField; |
| 5201 offset_in_bytes_ = store->offset_in_bytes(); | 5189 offset_in_bytes_ = store->offset_in_bytes(); |
| 5202 } | 5190 } |
| 5203 break; | 5191 break; |
| 5204 } | 5192 } |
| 5205 | 5193 |
| 5206 case Instruction::kLoadStaticField: | 5194 case Instruction::kLoadStaticField: |
| 5207 kind_ = kField; | 5195 kind_ = kField; |
| 5208 representation_ = instr->AsLoadStaticField()->representation(); | 5196 representation_ = instr->AsLoadStaticField()->representation(); |
| 5209 field_ = &instr->AsLoadStaticField()->StaticField(); | 5197 field_ = &instr->AsLoadStaticField()->StaticField(); |
| 5210 *is_load = true; | 5198 *is_load = true; |
| 5211 break; | 5199 break; |
| 5212 | 5200 |
| 5213 case Instruction::kStoreStaticField: | 5201 case Instruction::kStoreStaticField: |
| 5214 kind_ = kField; | 5202 kind_ = kField; |
| 5215 representation_ = instr->AsStoreStaticField()-> | 5203 representation_ = instr->AsStoreStaticField()-> |
| 5216 RequiredInputRepresentation(StoreStaticFieldInstr::kValuePos); | 5204 RequiredInputRepresentation(StoreStaticFieldInstr::kValuePos); |
| 5217 field_ = &instr->AsStoreStaticField()->field(); | 5205 field_ = &instr->AsStoreStaticField()->field(); |
| 5218 break; | 5206 break; |
| 5219 | 5207 |
| 5220 case Instruction::kLoadIndexed: { | 5208 case Instruction::kLoadIndexed: { |
| 5221 LoadIndexedInstr* load_indexed = instr->AsLoadIndexed(); | 5209 LoadIndexedInstr* load_indexed = instr->AsLoadIndexed(); |
| 5222 kind_ = kIndexed; | 5210 kind_ = kIndexed; |
| 5223 representation_ = load_indexed->representation(); | 5211 representation_ = load_indexed->representation(); |
| 5224 instance_ = OriginalDefinition(load_indexed->array()->definition()); | 5212 instance_ = load_indexed->array()->definition()->OriginalDefinition(); |
| 5225 index_ = load_indexed->index()->definition(); | 5213 index_ = load_indexed->index()->definition(); |
| 5226 *is_load = true; | 5214 *is_load = true; |
| 5227 break; | 5215 break; |
| 5228 } | 5216 } |
| 5229 | 5217 |
| 5230 case Instruction::kStoreIndexed: { | 5218 case Instruction::kStoreIndexed: { |
| 5231 StoreIndexedInstr* store_indexed = instr->AsStoreIndexed(); | 5219 StoreIndexedInstr* store_indexed = instr->AsStoreIndexed(); |
| 5232 kind_ = kIndexed; | 5220 kind_ = kIndexed; |
| 5233 representation_ = store_indexed-> | 5221 representation_ = store_indexed-> |
| 5234 RequiredInputRepresentation(StoreIndexedInstr::kValuePos); | 5222 RequiredInputRepresentation(StoreIndexedInstr::kValuePos); |
| 5235 instance_ = OriginalDefinition(store_indexed->array()->definition()); | 5223 instance_ = store_indexed->array()->definition()->OriginalDefinition(); |
| 5236 index_ = store_indexed->index()->definition(); | 5224 index_ = store_indexed->index()->definition(); |
| 5237 break; | 5225 break; |
| 5238 } | 5226 } |
| 5239 | 5227 |
| 5240 case Instruction::kCurrentContext: | 5228 case Instruction::kCurrentContext: |
| 5241 kind_ = kContext; | 5229 kind_ = kContext; |
| 5242 ASSERT(instr->AsCurrentContext()->representation() == kTagged); | 5230 ASSERT(instr->AsCurrentContext()->representation() == kTagged); |
| 5243 representation_ = kTagged; | 5231 representation_ = kTagged; |
| 5244 *is_load = true; | 5232 *is_load = true; |
| 5245 break; | 5233 break; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 5263 | 5251 |
| 5264 Representation representation() const { return representation_; } | 5252 Representation representation() const { return representation_; } |
| 5265 | 5253 |
| 5266 Definition* instance() const { | 5254 Definition* instance() const { |
| 5267 ASSERT((kind_ == kField) || (kind_ == kVMField) || (kind_ == kIndexed)); | 5255 ASSERT((kind_ == kField) || (kind_ == kVMField) || (kind_ == kIndexed)); |
| 5268 return instance_; | 5256 return instance_; |
| 5269 } | 5257 } |
| 5270 | 5258 |
| 5271 void set_instance(Definition* def) { | 5259 void set_instance(Definition* def) { |
| 5272 ASSERT((kind_ == kField) || (kind_ == kVMField) || (kind_ == kIndexed)); | 5260 ASSERT((kind_ == kField) || (kind_ == kVMField) || (kind_ == kIndexed)); |
| 5273 instance_ = OriginalDefinition(def); | 5261 instance_ = def->OriginalDefinition(); |
| 5274 } | 5262 } |
| 5275 | 5263 |
| 5276 const Field& field() const { | 5264 const Field& field() const { |
| 5277 ASSERT(kind_ == kField); | 5265 ASSERT(kind_ == kField); |
| 5278 return *field_; | 5266 return *field_; |
| 5279 } | 5267 } |
| 5280 | 5268 |
| 5281 intptr_t offset_in_bytes() const { | 5269 intptr_t offset_in_bytes() const { |
| 5282 ASSERT(kind_ == kVMField); | 5270 ASSERT(kind_ == kVMField); |
| 5283 return offset_in_bytes_; | 5271 return offset_in_bytes_; |
| (...skipping 3769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9053 } | 9041 } |
| 9054 | 9042 |
| 9055 // Insert materializations at environment uses. | 9043 // Insert materializations at environment uses. |
| 9056 for (intptr_t i = 0; i < exits.length(); i++) { | 9044 for (intptr_t i = 0; i < exits.length(); i++) { |
| 9057 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *slots); | 9045 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *slots); |
| 9058 } | 9046 } |
| 9059 } | 9047 } |
| 9060 | 9048 |
| 9061 | 9049 |
| 9062 } // namespace dart | 9050 } // namespace dart |
| OLD | NEW |