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/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 858 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
869 // callee functions, then no class check is needed. | 869 // callee functions, then no class check is needed. |
870 bool FlowGraphOptimizer::InstanceCallNeedsClassCheck( | 870 bool FlowGraphOptimizer::InstanceCallNeedsClassCheck( |
871 InstanceCallInstr* call) const { | 871 InstanceCallInstr* call) const { |
872 if (!FLAG_use_cha) return true; | 872 if (!FLAG_use_cha) return true; |
873 Definition* callee_receiver = call->ArgumentAt(0)->value()->definition(); | 873 Definition* callee_receiver = call->ArgumentAt(0)->value()->definition(); |
874 ASSERT(callee_receiver != NULL); | 874 ASSERT(callee_receiver != NULL); |
875 const Function& function = flow_graph_->parsed_function().function(); | 875 const Function& function = flow_graph_->parsed_function().function(); |
876 if (function.IsDynamicFunction() && | 876 if (function.IsDynamicFunction() && |
877 callee_receiver->IsParameter() && | 877 callee_receiver->IsParameter() && |
878 (callee_receiver->AsParameter()->index() == 0)) { | 878 (callee_receiver->AsParameter()->index() == 0)) { |
879 const intptr_t static_receiver_cid = Class::Handle(function.Owner()).id(); | 879 return CHA::HasOverride(Class::Handle(function.Owner()), |
880 ZoneGrowableArray<intptr_t>* subclass_cids = | 880 call->function_name()); |
881 CHA::GetSubclassIdsOf(static_receiver_cid); | |
882 if (subclass_cids->is_empty()) { | |
883 // No subclasses, no check needed. | |
884 return false; | |
885 } | |
886 ZoneGrowableArray<Function*>* overriding_functions = | |
887 CHA::GetNamedInstanceFunctionsOf(*subclass_cids, call->function_name()); | |
888 if (overriding_functions->is_empty()) { | |
889 // No overriding functions. | |
890 return false; | |
891 } | |
892 } | 881 } |
893 return true; | 882 return true; |
894 } | 883 } |
895 | 884 |
896 | 885 |
897 void FlowGraphOptimizer::InlineImplicitInstanceGetter(InstanceCallInstr* call) { | 886 void FlowGraphOptimizer::InlineImplicitInstanceGetter(InstanceCallInstr* call) { |
898 ASSERT(call->HasICData()); | 887 ASSERT(call->HasICData()); |
899 const ICData& ic_data = *call->ic_data(); | 888 const ICData& ic_data = *call->ic_data(); |
900 Function& target = Function::Handle(); | 889 Function& target = Function::Handle(); |
901 GrowableArray<intptr_t> class_ids; | 890 GrowableArray<intptr_t> class_ids; |
(...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1148 TryReplaceWithBinaryOp(instr, op_kind)) { | 1137 TryReplaceWithBinaryOp(instr, op_kind)) { |
1149 return; | 1138 return; |
1150 } | 1139 } |
1151 if (Token::IsPrefixOperator(op_kind) && | 1140 if (Token::IsPrefixOperator(op_kind) && |
1152 TryReplaceWithUnaryOp(instr, op_kind)) { | 1141 TryReplaceWithUnaryOp(instr, op_kind)) { |
1153 return; | 1142 return; |
1154 } | 1143 } |
1155 if ((op_kind == Token::kGET) && TryInlineInstanceGetter(instr)) { | 1144 if ((op_kind == Token::kGET) && TryInlineInstanceGetter(instr)) { |
1156 return; | 1145 return; |
1157 } | 1146 } |
1158 if ((op_kind == Token::kSET) && TryInlineInstanceSetter(instr)) { | 1147 if ((op_kind == Token::kSET) && |
| 1148 TryInlineInstanceSetter(instr, unary_checks)) { |
1159 return; | 1149 return; |
1160 } | 1150 } |
1161 if (TryInlineInstanceMethod(instr)) { | 1151 if (TryInlineInstanceMethod(instr)) { |
1162 return; | 1152 return; |
1163 } | 1153 } |
1164 if (!InstanceCallNeedsClassCheck(instr)) { | 1154 if (!InstanceCallNeedsClassCheck(instr)) { |
1165 const bool call_with_checks = false; | 1155 const bool call_with_checks = false; |
1166 PolymorphicInstanceCallInstr* call = | 1156 PolymorphicInstanceCallInstr* call = |
1167 new PolymorphicInstanceCallInstr(instr, unary_checks, | 1157 new PolymorphicInstanceCallInstr(instr, unary_checks, |
1168 call_with_checks); | 1158 call_with_checks); |
(...skipping 22 matching lines...) Expand all Loading... |
1191 MethodRecognizer::Kind recognized_kind = | 1181 MethodRecognizer::Kind recognized_kind = |
1192 MethodRecognizer::RecognizeKind(call->function()); | 1182 MethodRecognizer::RecognizeKind(call->function()); |
1193 if (recognized_kind == MethodRecognizer::kMathSqrt) { | 1183 if (recognized_kind == MethodRecognizer::kMathSqrt) { |
1194 MathSqrtInstr* sqrt = new MathSqrtInstr(call->ArgumentAt(0)->value(), call); | 1184 MathSqrtInstr* sqrt = new MathSqrtInstr(call->ArgumentAt(0)->value(), call); |
1195 call->ReplaceWith(sqrt, current_iterator()); | 1185 call->ReplaceWith(sqrt, current_iterator()); |
1196 RemovePushArguments(call); | 1186 RemovePushArguments(call); |
1197 } | 1187 } |
1198 } | 1188 } |
1199 | 1189 |
1200 | 1190 |
1201 bool FlowGraphOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr) { | 1191 bool FlowGraphOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr, |
| 1192 const ICData& unary_ic_data) { |
| 1193 ASSERT((unary_ic_data.NumberOfChecks() > 0) && |
| 1194 (unary_ic_data.num_args_tested() == 1)); |
1202 if (FLAG_enable_type_checks) { | 1195 if (FLAG_enable_type_checks) { |
1203 // TODO(srdjan): Add assignable check node if --enable_type_checks. | 1196 // TODO(srdjan): Add assignable check node if --enable_type_checks. |
1204 return false; | 1197 return false; |
1205 } | 1198 } |
1206 | 1199 |
1207 ASSERT(instr->HasICData()); | 1200 ASSERT(instr->HasICData()); |
1208 const ICData& unary_ic_data = | |
1209 ICData::Handle(instr->ic_data()->AsUnaryClassChecks()); | |
1210 if (unary_ic_data.NumberOfChecks() == 0) { | 1201 if (unary_ic_data.NumberOfChecks() == 0) { |
1211 // No type feedback collected. | 1202 // No type feedback collected. |
1212 return false; | 1203 return false; |
1213 } | 1204 } |
1214 if (!unary_ic_data.HasOneTarget()) { | 1205 if (!unary_ic_data.HasOneTarget()) { |
1215 // TODO(srdjan): Implement when not all targets are the same. | 1206 // TODO(srdjan): Implement when not all targets are the same. |
1216 return false; | 1207 return false; |
1217 } | 1208 } |
1218 Function& target = Function::Handle(); | 1209 Function& target = Function::Handle(); |
1219 intptr_t class_id; | 1210 intptr_t class_id; |
(...skipping 2435 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3655 | 3646 |
3656 if (FLAG_trace_constant_propagation) { | 3647 if (FLAG_trace_constant_propagation) { |
3657 OS::Print("\n==== After constant propagation ====\n"); | 3648 OS::Print("\n==== After constant propagation ====\n"); |
3658 FlowGraphPrinter printer(*graph_); | 3649 FlowGraphPrinter printer(*graph_); |
3659 printer.PrintBlocks(); | 3650 printer.PrintBlocks(); |
3660 } | 3651 } |
3661 } | 3652 } |
3662 | 3653 |
3663 | 3654 |
3664 } // namespace dart | 3655 } // namespace dart |
OLD | NEW |