| 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/aot_optimizer.h" | 5 #include "vm/aot_optimizer.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/branch_optimizer.h" | 8 #include "vm/branch_optimizer.h" |
| 9 #include "vm/cha.h" | 9 #include "vm/cha.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 2029 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2040 TryAddTest(results, kDoubleCid, true); | 2040 TryAddTest(results, kDoubleCid, true); |
| 2041 return false; | 2041 return false; |
| 2042 } else if (type.IsDoubleType()) { | 2042 } else if (type.IsDoubleType()) { |
| 2043 ASSERT((*results)[0] == kSmiCid); | 2043 ASSERT((*results)[0] == kSmiCid); |
| 2044 TryAddTest(results, kDoubleCid, true); | 2044 TryAddTest(results, kDoubleCid, true); |
| 2045 return false; | 2045 return false; |
| 2046 } | 2046 } |
| 2047 return true; // May deoptimize since we have not identified all 'true' tests. | 2047 return true; // May deoptimize since we have not identified all 'true' tests. |
| 2048 } | 2048 } |
| 2049 | 2049 |
| 2050 // Tells whether the function of the call matches the core private name. |
| 2051 static bool matches_core(InstanceCallInstr* call, const String& name) { |
| 2052 return call->function_name().raw() == Library::PrivateCoreLibName(name).raw(); |
| 2053 } |
| 2050 | 2054 |
| 2051 // TODO(srdjan): Use ICData to check if always true or false. | 2055 // TODO(srdjan): Use ICData to check if always true or false. |
| 2052 void AotOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) { | 2056 void AotOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) { |
| 2053 ASSERT(Token::IsTypeTestOperator(call->token_kind())); | 2057 ASSERT(Token::IsTypeTestOperator(call->token_kind())); |
| 2054 Definition* left = call->ArgumentAt(0); | 2058 Definition* left = call->ArgumentAt(0); |
| 2055 Definition* type_args = NULL; | 2059 Definition* type_args = NULL; |
| 2056 AbstractType& type = AbstractType::ZoneHandle(Z); | 2060 AbstractType& type = AbstractType::ZoneHandle(Z); |
| 2057 bool negate = false; | 2061 bool negate = false; |
| 2058 if (call->ArgumentCount() == 2) { | 2062 if (call->ArgumentCount() == 2) { |
| 2059 type_args = flow_graph()->constant_null(); | 2063 type_args = flow_graph()->constant_null(); |
| 2060 if (call->function_name().raw() == | 2064 if (matches_core(call, Symbols::_simpleInstanceOf())) { |
| 2061 Library::PrivateCoreLibName(Symbols::_instanceOfNum()).raw()) { | 2065 type = |
| 2062 type = Type::Number(); | 2066 AbstractType::Cast(call->ArgumentAt(1)->AsConstant()->value()).raw(); |
| 2063 } else if (call->function_name().raw() == | 2067 negate = false; // Just to be sure. |
| 2064 Library::PrivateCoreLibName(Symbols::_instanceOfInt()).raw()) { | |
| 2065 type = Type::IntType(); | |
| 2066 } else if (call->function_name().raw() == | |
| 2067 Library::PrivateCoreLibName(Symbols::_instanceOfSmi()).raw()) { | |
| 2068 type = Type::SmiType(); | |
| 2069 } else if (call->function_name().raw() == | |
| 2070 Library::PrivateCoreLibName(Symbols::_instanceOfDouble()).raw()) { | |
| 2071 type = Type::Double(); | |
| 2072 } else if (call->function_name().raw() == | |
| 2073 Library::PrivateCoreLibName(Symbols::_instanceOfString()).raw()) { | |
| 2074 type = Type::StringType(); | |
| 2075 } else { | 2068 } else { |
| 2076 UNIMPLEMENTED(); | 2069 if (matches_core(call, Symbols::_instanceOfNum())) { |
| 2070 type = Type::Number(); |
| 2071 } else if (matches_core(call, Symbols::_instanceOfInt())) { |
| 2072 type = Type::IntType(); |
| 2073 } else if (matches_core(call, Symbols::_instanceOfSmi())) { |
| 2074 type = Type::SmiType(); |
| 2075 } else if (matches_core(call, Symbols::_instanceOfDouble())) { |
| 2076 type = Type::Double(); |
| 2077 } else if (matches_core(call, Symbols::_instanceOfString())) { |
| 2078 type = Type::StringType(); |
| 2079 } else { |
| 2080 UNIMPLEMENTED(); |
| 2081 } |
| 2082 negate = Bool::Cast(call->ArgumentAt(1)->OriginalDefinition() |
| 2083 ->AsConstant()->value()).value(); |
| 2077 } | 2084 } |
| 2078 negate = Bool::Cast(call->ArgumentAt(1)->OriginalDefinition() | |
| 2079 ->AsConstant()->value()).value(); | |
| 2080 } else { | 2085 } else { |
| 2081 type_args = call->ArgumentAt(1); | 2086 type_args = call->ArgumentAt(1); |
| 2082 type = AbstractType::Cast(call->ArgumentAt(2)->AsConstant()->value()).raw(); | 2087 type = AbstractType::Cast(call->ArgumentAt(2)->AsConstant()->value()).raw(); |
| 2083 negate = Bool::Cast(call->ArgumentAt(3)->OriginalDefinition() | 2088 negate = Bool::Cast(call->ArgumentAt(3)->OriginalDefinition() |
| 2084 ->AsConstant()->value()).value(); | 2089 ->AsConstant()->value()).value(); |
| 2085 } | 2090 } |
| 2086 | 2091 |
| 2087 if (TypeCheckAsClassEquality(type)) { | 2092 if (TypeCheckAsClassEquality(type)) { |
| 2088 LoadClassIdInstr* left_cid = new(Z) LoadClassIdInstr(new(Z) Value(left)); | 2093 LoadClassIdInstr* left_cid = new(Z) LoadClassIdInstr(new(Z) Value(left)); |
| 2089 InsertBefore(call, | 2094 InsertBefore(call, |
| (...skipping 669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2759 flow_graph_->InsertBefore(check, new_check, | 2764 flow_graph_->InsertBefore(check, new_check, |
| 2760 check->env(), FlowGraph::kEffect); | 2765 check->env(), FlowGraph::kEffect); |
| 2761 current_iterator()->RemoveCurrentFromGraph(); | 2766 current_iterator()->RemoveCurrentFromGraph(); |
| 2762 } | 2767 } |
| 2763 } | 2768 } |
| 2764 } | 2769 } |
| 2765 } | 2770 } |
| 2766 | 2771 |
| 2767 | 2772 |
| 2768 } // namespace dart | 2773 } // namespace dart |
| OLD | NEW |