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

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

Issue 11275110: Do not recompute unary_checks repeatedly. Add special (and quicker) way to check for method overrid… (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month 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
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/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
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
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
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
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
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698