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

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

Issue 11416129: Inline [] operator on one-byte strings. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: removed unnecessary change Created 8 years 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') | 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 1089 matching lines...) Expand 10 before | Expand all | Expand 10 after
1100 return false; 1100 return false;
1101 } 1101 }
1102 InlineStringIsEmptyGetter(call); 1102 InlineStringIsEmptyGetter(call);
1103 return true; 1103 return true;
1104 } 1104 }
1105 1105
1106 return false; 1106 return false;
1107 } 1107 }
1108 1108
1109 1109
1110 StringCharCodeAtInstr* FlowGraphOptimizer::BuildStringCharCodeAt(
1111 InstanceCallInstr* call,
1112 intptr_t cid) {
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 }
srdjan 2012/11/21 16:38:15 Why not just return the value instead? Is that han
Florian Schneider 2012/11/22 11:05:58 This helper builds the graph for charCodeAt, which
1132 }
1133 if (!skip_check) {
1134 // Insert bounds check.
1135 InsertBefore(call,
1136 new CheckArrayBoundInstr(str->Copy(),
1137 index->Copy(),
1138 cid,
1139 call),
1140 call->env(),
1141 Definition::kEffect);
1142 }
1143 return new StringCharCodeAtInstr(str, index, cid);
1144 }
1145
1146
1110 // Inline only simple, frequently called core library methods. 1147 // Inline only simple, frequently called core library methods.
1111 bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { 1148 bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) {
1112 ASSERT(call->HasICData()); 1149 ASSERT(call->HasICData());
1113 const ICData& ic_data = *call->ic_data(); 1150 const ICData& ic_data = *call->ic_data();
1114 if ((ic_data.NumberOfChecks() == 0) || !ic_data.HasOneTarget()) { 1151 if ((ic_data.NumberOfChecks() == 0) || !ic_data.HasOneTarget()) {
1115 // No type feedback collected or multiple targets found. 1152 // No type feedback collected or multiple targets found.
1116 return false; 1153 return false;
1117 } 1154 }
1118 Function& target = Function::Handle(); 1155 Function& target = Function::Handle();
1119 GrowableArray<intptr_t> class_ids; 1156 GrowableArray<intptr_t> class_ids;
1120 ic_data.GetCheckAt(0, &class_ids, &target); 1157 ic_data.GetCheckAt(0, &class_ids, &target);
1121 MethodRecognizer::Kind recognized_kind = 1158 MethodRecognizer::Kind recognized_kind =
1122 MethodRecognizer::RecognizeKind(target); 1159 MethodRecognizer::RecognizeKind(target);
1123 if ((recognized_kind == MethodRecognizer::kStringBaseCharCodeAt) && 1160 if ((recognized_kind == MethodRecognizer::kStringBaseCharCodeAt) &&
1124 (ic_data.NumberOfChecks() == 1) && 1161 (ic_data.NumberOfChecks() == 1) &&
1125 ((class_ids[0] == kOneByteStringCid) || 1162 ((class_ids[0] == kOneByteStringCid) ||
1126 (class_ids[0] == kTwoByteStringCid))) { 1163 (class_ids[0] == kTwoByteStringCid))) {
1127 Value* str= call->ArgumentAt(0)->value(); 1164 StringCharCodeAtInstr* instr = BuildStringCharCodeAt(call, class_ids[0]);
1128 Value* index = call->ArgumentAt(1)->value();
1129 AddCheckClass(call, str->Copy());
1130 InsertBefore(call,
1131 new CheckSmiInstr(index->Copy(), call->deopt_id()),
1132 call->env(),
1133 Definition::kEffect);
1134 // If both index and string are constants, then do a compile-time check.
1135 // TODO(srdjan): Remove once constant propagation handles bounds checks.
1136 bool skip_check = false;
1137 if (str->BindsToConstant() && index->BindsToConstant()) {
1138 ConstantInstr* string_def = str->definition()->AsConstant();
1139 const String& constant_string =
1140 String::Cast(string_def->value());
1141 ConstantInstr* index_def = index->definition()->AsConstant();
1142 if (index_def->value().IsSmi()) {
1143 intptr_t constant_index = Smi::Cast(index_def->value()).Value();
1144 skip_check = (constant_index < constant_string.Length());
1145 }
1146 }
1147 if (!skip_check) {
1148 // Insert bounds check.
1149 InsertBefore(call,
1150 new CheckArrayBoundInstr(str->Copy(),
1151 index->Copy(),
1152 class_ids[0],
1153 call),
1154 call->env(),
1155 Definition::kEffect);
1156 }
1157 StringCharCodeAtInstr* instr =
1158 new StringCharCodeAtInstr(str, index, class_ids[0]);
1159 call->ReplaceWith(instr, current_iterator()); 1165 call->ReplaceWith(instr, current_iterator());
1160 RemovePushArguments(call); 1166 RemovePushArguments(call);
1161 return true; 1167 return true;
1162 } 1168 }
1169 if ((recognized_kind == MethodRecognizer::kStringBaseCharAt) &&
1170 (ic_data.NumberOfChecks() == 1) &&
1171 (class_ids[0] == kOneByteStringCid)) {
1172 // TODO(fschneider): Handle TwoByteString.
1173 StringCharCodeAtInstr* load_char_code =
1174 BuildStringCharCodeAt(call, class_ids[0]);
1175 InsertBefore(call, load_char_code, NULL, Definition::kValue);
1176 StringFromCharCodeInstr* char_at =
1177 new StringFromCharCodeInstr(new Value(load_char_code));
1178 call->ReplaceWith(char_at, current_iterator());
1179 RemovePushArguments(call);
1180 return true;
1181 }
1163 1182
1164 if ((recognized_kind == MethodRecognizer::kIntegerToDouble) && 1183 if ((recognized_kind == MethodRecognizer::kIntegerToDouble) &&
1165 (class_ids[0] == kSmiCid)) { 1184 (class_ids[0] == kSmiCid)) {
1166 SmiToDoubleInstr* s2d_instr = new SmiToDoubleInstr(call); 1185 SmiToDoubleInstr* s2d_instr = new SmiToDoubleInstr(call);
1167 call->ReplaceWith(s2d_instr, current_iterator()); 1186 call->ReplaceWith(s2d_instr, current_iterator());
1168 // Pushed arguments are not removed because SmiToDouble is implemented 1187 // Pushed arguments are not removed because SmiToDouble is implemented
1169 // as a call. 1188 // as a call.
1170 return true; 1189 return true;
1171 } 1190 }
1172 1191
(...skipping 2122 matching lines...) Expand 10 before | Expand all | Expand 10 after
3295 void ConstantPropagator::VisitNativeCall(NativeCallInstr* instr) { 3314 void ConstantPropagator::VisitNativeCall(NativeCallInstr* instr) {
3296 SetValue(instr, non_constant_); 3315 SetValue(instr, non_constant_);
3297 } 3316 }
3298 3317
3299 3318
3300 void ConstantPropagator::VisitStringCharCodeAt(StringCharCodeAtInstr* instr) { 3319 void ConstantPropagator::VisitStringCharCodeAt(StringCharCodeAtInstr* instr) {
3301 SetValue(instr, non_constant_); 3320 SetValue(instr, non_constant_);
3302 } 3321 }
3303 3322
3304 3323
3324 void ConstantPropagator::VisitStringFromCharCode(
3325 StringFromCharCodeInstr* instr) {
3326 SetValue(instr, non_constant_);
3327 }
3328
3329
3305 void ConstantPropagator::VisitLoadIndexed(LoadIndexedInstr* instr) { 3330 void ConstantPropagator::VisitLoadIndexed(LoadIndexedInstr* instr) {
3306 SetValue(instr, non_constant_); 3331 SetValue(instr, non_constant_);
3307 } 3332 }
3308 3333
3309 3334
3310 void ConstantPropagator::VisitStoreIndexed(StoreIndexedInstr* instr) { 3335 void ConstantPropagator::VisitStoreIndexed(StoreIndexedInstr* instr) {
3311 SetValue(instr, instr->value()->definition()->constant_value()); 3336 SetValue(instr, instr->value()->definition()->constant_value());
3312 } 3337 }
3313 3338
3314 3339
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after
3732 3757
3733 if (FLAG_trace_constant_propagation) { 3758 if (FLAG_trace_constant_propagation) {
3734 OS::Print("\n==== After constant propagation ====\n"); 3759 OS::Print("\n==== After constant propagation ====\n");
3735 FlowGraphPrinter printer(*graph_); 3760 FlowGraphPrinter printer(*graph_);
3736 printer.PrintBlocks(); 3761 printer.PrintBlocks();
3737 } 3762 }
3738 } 3763 }
3739 3764
3740 3765
3741 } // namespace dart 3766 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698