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

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

Issue 11360033: Inline native String.charCodeAt in optimized code. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: addressed comments 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/code_generator.h ('k') | runtime/vm/intermediate_language.h » ('j') | 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 452 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 Value** index) { 463 Value** index) {
464 *array = call->ArgumentAt(0)->value(); 464 *array = call->ArgumentAt(0)->value();
465 *index = call->ArgumentAt(1)->value(); 465 *index = call->ArgumentAt(1)->value();
466 // Insert class check and index smi checks and attach a copy of the 466 // Insert class check and index smi checks and attach a copy of the
467 // original environment because the operation can still deoptimize. 467 // original environment because the operation can still deoptimize.
468 AddCheckClass(call, (*array)->Copy()); 468 AddCheckClass(call, (*array)->Copy());
469 InsertBefore(call, 469 InsertBefore(call,
470 new CheckSmiInstr((*index)->Copy(), call->deopt_id()), 470 new CheckSmiInstr((*index)->Copy(), call->deopt_id()),
471 call->env(), 471 call->env(),
472 Definition::kEffect); 472 Definition::kEffect);
473 // If both index and array are constants, then the bound check always 473 // If both index and array are constants, then do a compile-time check.
474 // succeeded. 474 // TODO(srdjan): Remove once constant propagation handles bounds checks.
475 // TODO(srdjan): Remove once constant propagation lands. 475 bool skip_check = false;
476 if (!((*array)->BindsToConstant() && (*index)->BindsToConstant())) { 476 if ((*array)->BindsToConstant() && (*index)->BindsToConstant()) {
477 ConstantInstr* array_def = (*array)->definition()->AsConstant();
478 const ImmutableArray& constant_array =
479 ImmutableArray::Cast(array_def->value());
480 ConstantInstr* index_def = (*index)->definition()->AsConstant();
481 if (index_def->value().IsSmi()) {
482 intptr_t constant_index = Smi::Cast(index_def->value()).Value();
483 skip_check = (constant_index < constant_array.Length());
484 }
485 }
486 if (!skip_check) {
477 // Insert array bounds check. 487 // Insert array bounds check.
478 InsertBefore(call, 488 InsertBefore(call,
479 new CheckArrayBoundInstr((*array)->Copy(), 489 new CheckArrayBoundInstr((*array)->Copy(),
480 (*index)->Copy(), 490 (*index)->Copy(),
481 class_id, 491 class_id,
482 call), 492 call),
483 call->env(), 493 call->env(),
484 Definition::kEffect); 494 Definition::kEffect);
485 } 495 }
486 if (class_id == kGrowableObjectArrayCid) { 496 if (class_id == kGrowableObjectArrayCid) {
(...skipping 602 matching lines...) Expand 10 before | Expand all | Expand 10 after
1089 const ICData& ic_data = *call->ic_data(); 1099 const ICData& ic_data = *call->ic_data();
1090 if ((ic_data.NumberOfChecks() == 0) || !ic_data.HasOneTarget()) { 1100 if ((ic_data.NumberOfChecks() == 0) || !ic_data.HasOneTarget()) {
1091 // No type feedback collected or multiple targets found. 1101 // No type feedback collected or multiple targets found.
1092 return false; 1102 return false;
1093 } 1103 }
1094 Function& target = Function::Handle(); 1104 Function& target = Function::Handle();
1095 GrowableArray<intptr_t> class_ids; 1105 GrowableArray<intptr_t> class_ids;
1096 ic_data.GetCheckAt(0, &class_ids, &target); 1106 ic_data.GetCheckAt(0, &class_ids, &target);
1097 MethodRecognizer::Kind recognized_kind = 1107 MethodRecognizer::Kind recognized_kind =
1098 MethodRecognizer::RecognizeKind(target); 1108 MethodRecognizer::RecognizeKind(target);
1109 if ((recognized_kind == MethodRecognizer::kStringBaseCharCodeAt) &&
1110 (ic_data.NumberOfChecks() == 1) &&
1111 ((class_ids[0] == kOneByteStringCid) ||
1112 (class_ids[0] == kTwoByteStringCid))) {
1113 Value* str= call->ArgumentAt(0)->value();
1114 Value* index = call->ArgumentAt(1)->value();
1115 AddCheckClass(call, str->Copy());
1116 InsertBefore(call,
1117 new CheckSmiInstr(index->Copy(), call->deopt_id()),
1118 call->env(),
1119 Definition::kEffect);
1120 // If both index and string are constants, then do a compile-time check.
1121 // TODO(srdjan): Remove once constant propagation handles bounds checks.
1122 bool skip_check = false;
1123 if (str->BindsToConstant() && index->BindsToConstant()) {
1124 ConstantInstr* string_def = str->definition()->AsConstant();
1125 const String& constant_string =
1126 String::Cast(string_def->value());
1127 ConstantInstr* index_def = index->definition()->AsConstant();
1128 if (index_def->value().IsSmi()) {
1129 intptr_t constant_index = Smi::Cast(index_def->value()).Value();
1130 skip_check = (constant_index < constant_string.Length());
1131 }
1132 }
1133 if (!skip_check) {
1134 // Insert bounds check.
1135 InsertBefore(call,
1136 new CheckArrayBoundInstr(str->Copy(),
1137 index->Copy(),
1138 class_ids[0],
1139 call),
1140 call->env(),
1141 Definition::kEffect);
1142 }
1143 StringCharCodeAtInstr* instr =
1144 new StringCharCodeAtInstr(str, index, class_ids[0]);
1145 call->ReplaceWith(instr, current_iterator());
1146 RemovePushArguments(call);
1147 return true;
1148 }
1099 1149
1100 if ((recognized_kind == MethodRecognizer::kIntegerToDouble) && 1150 if ((recognized_kind == MethodRecognizer::kIntegerToDouble) &&
1101 (class_ids[0] == kSmiCid)) { 1151 (class_ids[0] == kSmiCid)) {
1102 SmiToDoubleInstr* s2d_instr = new SmiToDoubleInstr(call); 1152 SmiToDoubleInstr* s2d_instr = new SmiToDoubleInstr(call);
1103 call->ReplaceWith(s2d_instr, current_iterator()); 1153 call->ReplaceWith(s2d_instr, current_iterator());
1104 // Pushed arguments are not removed because SmiToDouble is implemented 1154 // Pushed arguments are not removed because SmiToDouble is implemented
1105 // as a call. 1155 // as a call.
1106 return true; 1156 return true;
1107 } 1157 }
1108 1158
(...skipping 2114 matching lines...) Expand 10 before | Expand all | Expand 10 after
3223 SetValue(instr, non_constant_); 3273 SetValue(instr, non_constant_);
3224 } 3274 }
3225 } 3275 }
3226 3276
3227 3277
3228 void ConstantPropagator::VisitNativeCall(NativeCallInstr* instr) { 3278 void ConstantPropagator::VisitNativeCall(NativeCallInstr* instr) {
3229 SetValue(instr, non_constant_); 3279 SetValue(instr, non_constant_);
3230 } 3280 }
3231 3281
3232 3282
3283 void ConstantPropagator::VisitStringCharCodeAt(StringCharCodeAtInstr* instr) {
3284 SetValue(instr, non_constant_);
3285 }
3286
3287
3233 void ConstantPropagator::VisitLoadIndexed(LoadIndexedInstr* instr) { 3288 void ConstantPropagator::VisitLoadIndexed(LoadIndexedInstr* instr) {
3234 SetValue(instr, non_constant_); 3289 SetValue(instr, non_constant_);
3235 } 3290 }
3236 3291
3237 3292
3238 void ConstantPropagator::VisitStoreIndexed(StoreIndexedInstr* instr) { 3293 void ConstantPropagator::VisitStoreIndexed(StoreIndexedInstr* instr) {
3239 SetValue(instr, instr->value()->definition()->constant_value()); 3294 SetValue(instr, instr->value()->definition()->constant_value());
3240 } 3295 }
3241 3296
3242 3297
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
3655 3710
3656 if (FLAG_trace_constant_propagation) { 3711 if (FLAG_trace_constant_propagation) {
3657 OS::Print("\n==== After constant propagation ====\n"); 3712 OS::Print("\n==== After constant propagation ====\n");
3658 FlowGraphPrinter printer(*graph_); 3713 FlowGraphPrinter printer(*graph_);
3659 printer.PrintBlocks(); 3714 printer.PrintBlocks();
3660 } 3715 }
3661 } 3716 }
3662 3717
3663 3718
3664 } // namespace dart 3719 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/code_generator.h ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698