| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 1157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1168 Type::ZoneHandle(Type::SmiType())); | 1168 Type::ZoneHandle(Type::SmiType())); |
| 1169 length_load->set_result_cid(kSmiCid); | 1169 length_load->set_result_cid(kSmiCid); |
| 1170 length_load->set_recognized_kind(MethodRecognizer::kObjectArrayLength); | 1170 length_load->set_recognized_kind(MethodRecognizer::kObjectArrayLength); |
| 1171 | 1171 |
| 1172 call->ReplaceWith(length_load, current_iterator()); | 1172 call->ReplaceWith(length_load, current_iterator()); |
| 1173 RemovePushArguments(call); | 1173 RemovePushArguments(call); |
| 1174 } | 1174 } |
| 1175 | 1175 |
| 1176 | 1176 |
| 1177 static LoadFieldInstr* BuildLoadStringLength(Value* str) { | 1177 static LoadFieldInstr* BuildLoadStringLength(Value* str) { |
| 1178 const bool is_immutable = true; // String length is immutable. | 1178 // Treat length loads as mutable (i.e. affected by side effects) to avoid |
| 1179 // hoisting them since we can't hoist the preceding class-check. This |
| 1180 // is because of externalization of strings that affects their class-id. |
| 1181 const bool is_immutable = false; |
| 1179 LoadFieldInstr* load = new LoadFieldInstr( | 1182 LoadFieldInstr* load = new LoadFieldInstr( |
| 1180 str, | 1183 str, |
| 1181 String::length_offset(), | 1184 String::length_offset(), |
| 1182 Type::ZoneHandle(Type::SmiType()), | 1185 Type::ZoneHandle(Type::SmiType()), |
| 1183 is_immutable); | 1186 is_immutable); |
| 1184 load->set_result_cid(kSmiCid); | 1187 load->set_result_cid(kSmiCid); |
| 1188 load->set_recognized_kind(MethodRecognizer::kStringBaseLength); |
| 1185 return load; | 1189 return load; |
| 1186 } | 1190 } |
| 1187 | 1191 |
| 1188 | 1192 |
| 1189 void FlowGraphOptimizer::InlineStringLengthGetter(InstanceCallInstr* call) { | 1193 void FlowGraphOptimizer::InlineStringLengthGetter(InstanceCallInstr* call) { |
| 1190 // Check receiver class. | 1194 // Check receiver class. |
| 1191 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy()); | 1195 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy()); |
| 1192 | 1196 |
| 1193 LoadFieldInstr* load = BuildLoadStringLength(call->ArgumentAt(0)->value()); | 1197 LoadFieldInstr* load = BuildLoadStringLength(call->ArgumentAt(0)->value()); |
| 1194 load->set_recognized_kind(MethodRecognizer::kStringBaseLength); | |
| 1195 call->ReplaceWith(load, current_iterator()); | 1198 call->ReplaceWith(load, current_iterator()); |
| 1196 RemovePushArguments(call); | 1199 RemovePushArguments(call); |
| 1197 } | 1200 } |
| 1198 | 1201 |
| 1199 | 1202 |
| 1200 void FlowGraphOptimizer::InlineStringIsEmptyGetter(InstanceCallInstr* call) { | 1203 void FlowGraphOptimizer::InlineStringIsEmptyGetter(InstanceCallInstr* call) { |
| 1201 // Check receiver class. | 1204 // Check receiver class. |
| 1202 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy()); | 1205 AddCheckClass(call, call->ArgumentAt(0)->value()->Copy()); |
| 1203 | 1206 |
| 1204 LoadFieldInstr* load = BuildLoadStringLength(call->ArgumentAt(0)->value()); | 1207 LoadFieldInstr* load = BuildLoadStringLength(call->ArgumentAt(0)->value()); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1318 const String& constant_string = | 1321 const String& constant_string = |
| 1319 String::Cast(string_def->value()); | 1322 String::Cast(string_def->value()); |
| 1320 ConstantInstr* index_def = index->definition()->AsConstant(); | 1323 ConstantInstr* index_def = index->definition()->AsConstant(); |
| 1321 if (index_def->value().IsSmi()) { | 1324 if (index_def->value().IsSmi()) { |
| 1322 intptr_t constant_index = Smi::Cast(index_def->value()).Value(); | 1325 intptr_t constant_index = Smi::Cast(index_def->value()).Value(); |
| 1323 skip_check = (constant_index < constant_string.Length()); | 1326 skip_check = (constant_index < constant_string.Length()); |
| 1324 } | 1327 } |
| 1325 } | 1328 } |
| 1326 if (!skip_check) { | 1329 if (!skip_check) { |
| 1327 // Insert bounds check. | 1330 // Insert bounds check. |
| 1328 const bool is_immutable = true; | 1331 LoadFieldInstr* length = BuildLoadStringLength(str->Copy()); |
| 1329 LoadFieldInstr* length = new LoadFieldInstr( | |
| 1330 str->Copy(), | |
| 1331 CheckArrayBoundInstr::LengthOffsetFor(cid), | |
| 1332 Type::ZoneHandle(Type::SmiType()), | |
| 1333 is_immutable); | |
| 1334 length->set_result_cid(kSmiCid); | |
| 1335 length->set_recognized_kind(MethodRecognizer::kStringBaseLength); | |
| 1336 InsertBefore(call, length, NULL, Definition::kValue); | 1332 InsertBefore(call, length, NULL, Definition::kValue); |
| 1337 InsertBefore(call, | 1333 InsertBefore(call, |
| 1338 new CheckArrayBoundInstr(new Value(length), | 1334 new CheckArrayBoundInstr(new Value(length), |
| 1339 index->Copy(), | 1335 index->Copy(), |
| 1340 cid, | 1336 cid, |
| 1341 call), | 1337 call), |
| 1342 call->env(), | 1338 call->env(), |
| 1343 Definition::kEffect); | 1339 Definition::kEffect); |
| 1344 } | 1340 } |
| 1345 return new LoadIndexedInstr(str, | 1341 return new LoadIndexedInstr(str, |
| (...skipping 2913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4259 | 4255 |
| 4260 if (FLAG_trace_constant_propagation) { | 4256 if (FLAG_trace_constant_propagation) { |
| 4261 OS::Print("\n==== After constant propagation ====\n"); | 4257 OS::Print("\n==== After constant propagation ====\n"); |
| 4262 FlowGraphPrinter printer(*graph_); | 4258 FlowGraphPrinter printer(*graph_); |
| 4263 printer.PrintBlocks(); | 4259 printer.PrintBlocks(); |
| 4264 } | 4260 } |
| 4265 } | 4261 } |
| 4266 | 4262 |
| 4267 | 4263 |
| 4268 } // namespace dart | 4264 } // namespace dart |
| OLD | NEW |