| 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 1202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1213 } | 1213 } |
| 1214 InlineStringIsEmptyGetter(call); | 1214 InlineStringIsEmptyGetter(call); |
| 1215 return true; | 1215 return true; |
| 1216 default: | 1216 default: |
| 1217 ASSERT(recognized_kind == MethodRecognizer::kUnknown); | 1217 ASSERT(recognized_kind == MethodRecognizer::kUnknown); |
| 1218 } | 1218 } |
| 1219 return false; | 1219 return false; |
| 1220 } | 1220 } |
| 1221 | 1221 |
| 1222 | 1222 |
| 1223 StringCharCodeAtInstr* FlowGraphOptimizer::BuildStringCharCodeAt( | 1223 LoadIndexedInstr* FlowGraphOptimizer::BuildStringCharCodeAt( |
| 1224 InstanceCallInstr* call, | 1224 InstanceCallInstr* call, |
| 1225 intptr_t cid) { | 1225 intptr_t cid) { |
| 1226 Value* str = call->ArgumentAt(0)->value(); | 1226 Value* str = call->ArgumentAt(0)->value(); |
| 1227 Value* index = call->ArgumentAt(1)->value(); | 1227 Value* index = call->ArgumentAt(1)->value(); |
| 1228 AddCheckClass(call, str->Copy()); | 1228 AddCheckClass(call, str->Copy()); |
| 1229 InsertBefore(call, | 1229 InsertBefore(call, |
| 1230 new CheckSmiInstr(index->Copy(), call->deopt_id()), | 1230 new CheckSmiInstr(index->Copy(), call->deopt_id()), |
| 1231 call->env(), | 1231 call->env(), |
| 1232 Definition::kEffect); | 1232 Definition::kEffect); |
| 1233 // If both index and string are constants, then do a compile-time check. | 1233 // If both index and string are constants, then do a compile-time check. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1246 if (!skip_check) { | 1246 if (!skip_check) { |
| 1247 // Insert bounds check. | 1247 // Insert bounds check. |
| 1248 InsertBefore(call, | 1248 InsertBefore(call, |
| 1249 new CheckArrayBoundInstr(str->Copy(), | 1249 new CheckArrayBoundInstr(str->Copy(), |
| 1250 index->Copy(), | 1250 index->Copy(), |
| 1251 cid, | 1251 cid, |
| 1252 call), | 1252 call), |
| 1253 call->env(), | 1253 call->env(), |
| 1254 Definition::kEffect); | 1254 Definition::kEffect); |
| 1255 } | 1255 } |
| 1256 return new StringCharCodeAtInstr(str, index, cid); | 1256 return new LoadIndexedInstr(str, index, cid); |
| 1257 } | 1257 } |
| 1258 | 1258 |
| 1259 | 1259 |
| 1260 // Inline only simple, frequently called core library methods. | 1260 // Inline only simple, frequently called core library methods. |
| 1261 bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { | 1261 bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { |
| 1262 ASSERT(call->HasICData()); | 1262 ASSERT(call->HasICData()); |
| 1263 const ICData& ic_data = *call->ic_data(); | 1263 const ICData& ic_data = *call->ic_data(); |
| 1264 if ((ic_data.NumberOfChecks() == 0) || !ic_data.HasOneTarget()) { | 1264 if ((ic_data.NumberOfChecks() == 0) || !ic_data.HasOneTarget()) { |
| 1265 // No type feedback collected or multiple targets found. | 1265 // No type feedback collected or multiple targets found. |
| 1266 return false; | 1266 return false; |
| 1267 } | 1267 } |
| 1268 Function& target = Function::Handle(); | 1268 Function& target = Function::Handle(); |
| 1269 GrowableArray<intptr_t> class_ids; | 1269 GrowableArray<intptr_t> class_ids; |
| 1270 ic_data.GetCheckAt(0, &class_ids, &target); | 1270 ic_data.GetCheckAt(0, &class_ids, &target); |
| 1271 MethodRecognizer::Kind recognized_kind = | 1271 MethodRecognizer::Kind recognized_kind = |
| 1272 MethodRecognizer::RecognizeKind(target); | 1272 MethodRecognizer::RecognizeKind(target); |
| 1273 if ((recognized_kind == MethodRecognizer::kStringBaseCharCodeAt) && | 1273 if ((recognized_kind == MethodRecognizer::kStringBaseCharCodeAt) && |
| 1274 (ic_data.NumberOfChecks() == 1) && | 1274 (ic_data.NumberOfChecks() == 1) && |
| 1275 ((class_ids[0] == kOneByteStringCid) || | 1275 ((class_ids[0] == kOneByteStringCid) || |
| 1276 (class_ids[0] == kTwoByteStringCid))) { | 1276 (class_ids[0] == kTwoByteStringCid))) { |
| 1277 StringCharCodeAtInstr* instr = BuildStringCharCodeAt(call, class_ids[0]); | 1277 LoadIndexedInstr* instr = BuildStringCharCodeAt(call, class_ids[0]); |
| 1278 call->ReplaceWith(instr, current_iterator()); | 1278 call->ReplaceWith(instr, current_iterator()); |
| 1279 RemovePushArguments(call); | 1279 RemovePushArguments(call); |
| 1280 return true; | 1280 return true; |
| 1281 } | 1281 } |
| 1282 if ((recognized_kind == MethodRecognizer::kStringBaseCharAt) && | 1282 if ((recognized_kind == MethodRecognizer::kStringBaseCharAt) && |
| 1283 (ic_data.NumberOfChecks() == 1) && | 1283 (ic_data.NumberOfChecks() == 1) && |
| 1284 (class_ids[0] == kOneByteStringCid)) { | 1284 (class_ids[0] == kOneByteStringCid)) { |
| 1285 // TODO(fschneider): Handle TwoByteString. | 1285 // TODO(fschneider): Handle TwoByteString. |
| 1286 StringCharCodeAtInstr* load_char_code = | 1286 LoadIndexedInstr* load_char_code = |
| 1287 BuildStringCharCodeAt(call, class_ids[0]); | 1287 BuildStringCharCodeAt(call, class_ids[0]); |
| 1288 InsertBefore(call, load_char_code, NULL, Definition::kValue); | 1288 InsertBefore(call, load_char_code, NULL, Definition::kValue); |
| 1289 StringFromCharCodeInstr* char_at = | 1289 StringFromCharCodeInstr* char_at = |
| 1290 new StringFromCharCodeInstr(new Value(load_char_code), | 1290 new StringFromCharCodeInstr(new Value(load_char_code), |
| 1291 kOneByteStringCid); | 1291 kOneByteStringCid); |
| 1292 call->ReplaceWith(char_at, current_iterator()); | 1292 call->ReplaceWith(char_at, current_iterator()); |
| 1293 RemovePushArguments(call); | 1293 RemovePushArguments(call); |
| 1294 return true; | 1294 return true; |
| 1295 } | 1295 } |
| 1296 | 1296 |
| (...skipping 2732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4029 } | 4029 } |
| 4030 } | 4030 } |
| 4031 } | 4031 } |
| 4032 | 4032 |
| 4033 | 4033 |
| 4034 void ConstantPropagator::VisitNativeCall(NativeCallInstr* instr) { | 4034 void ConstantPropagator::VisitNativeCall(NativeCallInstr* instr) { |
| 4035 SetValue(instr, non_constant_); | 4035 SetValue(instr, non_constant_); |
| 4036 } | 4036 } |
| 4037 | 4037 |
| 4038 | 4038 |
| 4039 void ConstantPropagator::VisitStringCharCodeAt(StringCharCodeAtInstr* instr) { | |
| 4040 SetValue(instr, non_constant_); | |
| 4041 } | |
| 4042 | |
| 4043 | |
| 4044 void ConstantPropagator::VisitStringFromCharCode( | 4039 void ConstantPropagator::VisitStringFromCharCode( |
| 4045 StringFromCharCodeInstr* instr) { | 4040 StringFromCharCodeInstr* instr) { |
| 4046 SetValue(instr, non_constant_); | 4041 SetValue(instr, non_constant_); |
| 4047 } | 4042 } |
| 4048 | 4043 |
| 4049 | 4044 |
| 4050 void ConstantPropagator::VisitLoadIndexed(LoadIndexedInstr* instr) { | 4045 void ConstantPropagator::VisitLoadIndexed(LoadIndexedInstr* instr) { |
| 4051 SetValue(instr, non_constant_); | 4046 SetValue(instr, non_constant_); |
| 4052 } | 4047 } |
| 4053 | 4048 |
| (...skipping 465 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4519 | 4514 |
| 4520 if (FLAG_trace_constant_propagation) { | 4515 if (FLAG_trace_constant_propagation) { |
| 4521 OS::Print("\n==== After constant propagation ====\n"); | 4516 OS::Print("\n==== After constant propagation ====\n"); |
| 4522 FlowGraphPrinter printer(*graph_); | 4517 FlowGraphPrinter printer(*graph_); |
| 4523 printer.PrintBlocks(); | 4518 printer.PrintBlocks(); |
| 4524 } | 4519 } |
| 4525 } | 4520 } |
| 4526 | 4521 |
| 4527 | 4522 |
| 4528 } // namespace dart | 4523 } // namespace dart |
| OLD | NEW |