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

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

Issue 11367022: Any instance call with too many checks is left to be megamorphic. This helps with, e.g., LoadField … (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 | « no previous file | 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 1105 matching lines...) Expand 10 before | Expand all | Expand 10 after
1116 return true; 1116 return true;
1117 } 1117 }
1118 1118
1119 return false; 1119 return false;
1120 } 1120 }
1121 1121
1122 1122
1123 // Tries to optimize instance call by replacing it with a faster instruction 1123 // Tries to optimize instance call by replacing it with a faster instruction
1124 // (e.g, binary op, field load, ..). 1124 // (e.g, binary op, field load, ..).
1125 void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) { 1125 void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) {
1126 if (instr->HasICData() && (instr->ic_data()->NumberOfChecks() > 0)) { 1126 if (!instr->HasICData() || (instr->ic_data()->NumberOfChecks() == 0)) {
1127 const Token::Kind op_kind = instr->token_kind(); 1127 // An instance call without ICData will trigger deoptimization.
1128 if ((op_kind == Token::kASSIGN_INDEX) && 1128 return;
1129 TryReplaceWithStoreIndexed(instr)) { 1129 }
1130 return; 1130
1131 const ICData& unary_checks =
1132 ICData::ZoneHandle(instr->ic_data()->AsUnaryClassChecks());
1133 if ((unary_checks.NumberOfChecks() > FLAG_max_polymorphic_checks) &&
1134 InstanceCallNeedsClassCheck(instr)) {
1135 // Too many checks, leave it megamorphic.
1136 return;
1137 }
1138
1139 const Token::Kind op_kind = instr->token_kind();
1140 if ((op_kind == Token::kASSIGN_INDEX) &&
1141 TryReplaceWithStoreIndexed(instr)) {
1142 return;
1143 }
1144 if ((op_kind == Token::kINDEX) && TryReplaceWithLoadIndexed(instr)) {
1145 return;
1146 }
1147 if (Token::IsBinaryOperator(op_kind) &&
1148 TryReplaceWithBinaryOp(instr, op_kind)) {
1149 return;
1150 }
1151 if (Token::IsPrefixOperator(op_kind) &&
1152 TryReplaceWithUnaryOp(instr, op_kind)) {
1153 return;
1154 }
1155 if ((op_kind == Token::kGET) && TryInlineInstanceGetter(instr)) {
1156 return;
1157 }
1158 if ((op_kind == Token::kSET) && TryInlineInstanceSetter(instr)) {
1159 return;
1160 }
1161 if (TryInlineInstanceMethod(instr)) {
1162 return;
1163 }
1164 if (!InstanceCallNeedsClassCheck(instr)) {
1165 const bool call_with_checks = false;
1166 PolymorphicInstanceCallInstr* call =
1167 new PolymorphicInstanceCallInstr(instr, unary_checks,
1168 call_with_checks);
1169 instr->ReplaceWith(call, current_iterator());
1170 return;
1171 }
1172 if (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks) {
1173 bool call_with_checks;
1174 if (unary_checks.HasOneTarget()) {
1175 // Type propagation has not run yet, we cannot eliminate the check.
1176 AddCheckClass(instr, instr->ArgumentAt(0)->value()->Copy());
1177 // Call can still deoptimize, do not detach environment from instr.
1178 call_with_checks = false;
1179 } else {
1180 call_with_checks = true;
1131 } 1181 }
1132 if ((op_kind == Token::kINDEX) && TryReplaceWithLoadIndexed(instr)) { 1182 PolymorphicInstanceCallInstr* call =
1133 return; 1183 new PolymorphicInstanceCallInstr(instr, unary_checks,
1134 } 1184 call_with_checks);
1135 if (Token::IsBinaryOperator(op_kind) && 1185 instr->ReplaceWith(call, current_iterator());
1136 TryReplaceWithBinaryOp(instr, op_kind)) {
1137 return;
1138 }
1139 if (Token::IsPrefixOperator(op_kind) &&
1140 TryReplaceWithUnaryOp(instr, op_kind)) {
1141 return;
1142 }
1143 if ((op_kind == Token::kGET) && TryInlineInstanceGetter(instr)) {
1144 return;
1145 }
1146 if ((op_kind == Token::kSET) && TryInlineInstanceSetter(instr)) {
1147 return;
1148 }
1149 if (TryInlineInstanceMethod(instr)) {
1150 return;
1151 }
1152 const ICData& unary_checks =
1153 ICData::ZoneHandle(instr->ic_data()->AsUnaryClassChecks());
1154 if (!InstanceCallNeedsClassCheck(instr)) {
1155 const bool call_with_checks = false;
1156 PolymorphicInstanceCallInstr* call =
1157 new PolymorphicInstanceCallInstr(instr, unary_checks,
1158 call_with_checks);
1159 instr->ReplaceWith(call, current_iterator());
1160 return;
1161 }
1162 if (instr->ic_data()->NumberOfChecks() <= FLAG_max_polymorphic_checks) {
1163 bool call_with_checks;
1164 if (unary_checks.HasOneTarget()) {
1165 // Type propagation has not run yet, we cannot eliminate the check.
1166 AddCheckClass(instr, instr->ArgumentAt(0)->value()->Copy());
1167 // Call can still deoptimize, do not detach environment from instr.
1168 call_with_checks = false;
1169 } else {
1170 call_with_checks = true;
1171 }
1172 PolymorphicInstanceCallInstr* call =
1173 new PolymorphicInstanceCallInstr(instr, unary_checks,
1174 call_with_checks);
1175 instr->ReplaceWith(call, current_iterator());
1176 }
1177 } 1186 }
1178 // An instance call without ICData will trigger deoptimization.
1179 } 1187 }
1180 1188
1181 1189
1182 void FlowGraphOptimizer::VisitStaticCall(StaticCallInstr* call) { 1190 void FlowGraphOptimizer::VisitStaticCall(StaticCallInstr* call) {
1183 MethodRecognizer::Kind recognized_kind = 1191 MethodRecognizer::Kind recognized_kind =
1184 MethodRecognizer::RecognizeKind(call->function()); 1192 MethodRecognizer::RecognizeKind(call->function());
1185 if (recognized_kind == MethodRecognizer::kMathSqrt) { 1193 if (recognized_kind == MethodRecognizer::kMathSqrt) {
1186 MathSqrtInstr* sqrt = new MathSqrtInstr(call->ArgumentAt(0)->value(), call); 1194 MathSqrtInstr* sqrt = new MathSqrtInstr(call->ArgumentAt(0)->value(), call);
1187 call->ReplaceWith(sqrt, current_iterator()); 1195 call->ReplaceWith(sqrt, current_iterator());
1188 RemovePushArguments(call); 1196 RemovePushArguments(call);
(...skipping 2458 matching lines...) Expand 10 before | Expand all | Expand 10 after
3647 3655
3648 if (FLAG_trace_constant_propagation) { 3656 if (FLAG_trace_constant_propagation) {
3649 OS::Print("\n==== After constant propagation ====\n"); 3657 OS::Print("\n==== After constant propagation ====\n");
3650 FlowGraphPrinter printer(*graph_); 3658 FlowGraphPrinter printer(*graph_);
3651 printer.PrintBlocks(); 3659 printer.PrintBlocks();
3652 } 3660 }
3653 } 3661 }
3654 3662
3655 3663
3656 } // namespace dart 3664 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698