| 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/intermediate_language.h" | 5 #include "vm/intermediate_language.h" |
| 6 | 6 |
| 7 #include "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/bit_vector.h" | 8 #include "vm/bit_vector.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/flow_graph_allocator.h" | 10 #include "vm/flow_graph_allocator.h" |
| (...skipping 1267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1278 } | 1278 } |
| 1279 break; | 1279 break; |
| 1280 default: | 1280 default: |
| 1281 break; | 1281 break; |
| 1282 } | 1282 } |
| 1283 | 1283 |
| 1284 return NULL; | 1284 return NULL; |
| 1285 } | 1285 } |
| 1286 | 1286 |
| 1287 | 1287 |
| 1288 Definition* DoubleToFloatInstr::Canonicalize(FlowGraph* flow_graph) { |
| 1289 #ifdef DEBUG |
| 1290 // Must only be used in Float32 StoreIndexedInstr or FloatToDoubleInstr or |
| 1291 // Phis introduce by load forwarding. |
| 1292 ASSERT(env_use_list() == NULL); |
| 1293 for (Value* use = input_use_list(); |
| 1294 use != NULL; |
| 1295 use = use->next_use()) { |
| 1296 ASSERT(use->instruction()->IsPhi() || |
| 1297 use->instruction()->IsFloatToDouble() || |
| 1298 (use->instruction()->IsStoreIndexed() && |
| 1299 (use->instruction()->AsStoreIndexed()->class_id() == |
| 1300 kTypedDataFloat32ArrayCid))); |
| 1301 } |
| 1302 #endif |
| 1303 if (!HasUses()) return NULL; |
| 1304 if (value()->definition()->IsFloatToDouble()) { |
| 1305 // F2D(D2F(v)) == v. |
| 1306 return value()->definition()->AsFloatToDouble()->value()->definition(); |
| 1307 } |
| 1308 return this; |
| 1309 } |
| 1310 |
| 1311 |
| 1312 Definition* FloatToDoubleInstr::Canonicalize(FlowGraph* flow_graph) { |
| 1313 return HasUses() ? this : NULL; |
| 1314 } |
| 1315 |
| 1316 |
| 1288 Definition* BinaryDoubleOpInstr::Canonicalize(FlowGraph* flow_graph) { | 1317 Definition* BinaryDoubleOpInstr::Canonicalize(FlowGraph* flow_graph) { |
| 1289 Definition* result = NULL; | 1318 Definition* result = NULL; |
| 1290 | 1319 |
| 1291 result = CanonicalizeCommutativeArithmetic(op_kind(), | 1320 result = CanonicalizeCommutativeArithmetic(op_kind(), |
| 1292 kDoubleCid, | 1321 kDoubleCid, |
| 1293 left(), | 1322 left(), |
| 1294 right()); | 1323 right()); |
| 1295 if (result != NULL) { | 1324 if (result != NULL) { |
| 1296 return result; | 1325 return result; |
| 1297 } | 1326 } |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1428 | 1457 |
| 1429 | 1458 |
| 1430 Definition* LoadFieldInstr::Canonicalize(FlowGraph* flow_graph) { | 1459 Definition* LoadFieldInstr::Canonicalize(FlowGraph* flow_graph) { |
| 1431 if (!HasUses()) return NULL; | 1460 if (!HasUses()) return NULL; |
| 1432 if (!IsImmutableLengthLoad()) return this; | 1461 if (!IsImmutableLengthLoad()) return this; |
| 1433 | 1462 |
| 1434 // For fixed length arrays if the array is the result of a known constructor | 1463 // For fixed length arrays if the array is the result of a known constructor |
| 1435 // call we can replace the length load with the length argument passed to | 1464 // call we can replace the length load with the length argument passed to |
| 1436 // the constructor. | 1465 // the constructor. |
| 1437 StaticCallInstr* call = instance()->definition()->AsStaticCall(); | 1466 StaticCallInstr* call = instance()->definition()->AsStaticCall(); |
| 1438 if ((call != NULL) && | 1467 if (call != NULL) { |
| 1439 call->is_known_list_constructor() && | 1468 if (call->is_known_list_constructor() && |
| 1440 IsFixedLengthArrayCid(call->Type()->ToCid())) { | 1469 IsFixedLengthArrayCid(call->Type()->ToCid())) { |
| 1441 return call->ArgumentAt(1); | 1470 return call->ArgumentAt(1); |
| 1471 } |
| 1472 if (call->is_native_list_factory()) { |
| 1473 return call->ArgumentAt(0); |
| 1474 } |
| 1442 } | 1475 } |
| 1443 // For arrays with guarded lengths, replace the length load | 1476 // For arrays with guarded lengths, replace the length load |
| 1444 // with a constant. | 1477 // with a constant. |
| 1445 LoadFieldInstr* load_array = instance()->definition()->AsLoadField(); | 1478 LoadFieldInstr* load_array = instance()->definition()->AsLoadField(); |
| 1446 if (load_array != NULL) { | 1479 if (load_array != NULL) { |
| 1447 const Field* field = load_array->field(); | 1480 const Field* field = load_array->field(); |
| 1448 if ((field != NULL) && (field->guarded_list_length() >= 0)) { | 1481 if ((field != NULL) && (field->guarded_list_length() >= 0)) { |
| 1449 return flow_graph->GetConstant( | 1482 return flow_graph->GetConstant( |
| 1450 Smi::Handle(Smi::New(field->guarded_list_length()))); | 1483 Smi::Handle(Smi::New(field->guarded_list_length()))); |
| 1451 } | 1484 } |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1807 return unary_checks().HasReceiverClassId(value_cid) ? NULL : this; | 1840 return unary_checks().HasReceiverClassId(value_cid) ? NULL : this; |
| 1808 } | 1841 } |
| 1809 | 1842 |
| 1810 | 1843 |
| 1811 Instruction* GuardFieldInstr::Canonicalize(FlowGraph* flow_graph) { | 1844 Instruction* GuardFieldInstr::Canonicalize(FlowGraph* flow_graph) { |
| 1812 if (field().guarded_cid() == kDynamicCid) { | 1845 if (field().guarded_cid() == kDynamicCid) { |
| 1813 return NULL; // Nothing to guard. | 1846 return NULL; // Nothing to guard. |
| 1814 } | 1847 } |
| 1815 | 1848 |
| 1816 if (field().guarded_list_length() != Field::kNoFixedLength) { | 1849 if (field().guarded_list_length() != Field::kNoFixedLength) { |
| 1817 // We are still guarding the list length. | 1850 // We are still guarding the list length. Check if length is statically |
| 1851 // known. |
| 1852 StaticCallInstr* call = value()->definition()->AsStaticCall(); |
| 1853 if (call != NULL) { |
| 1854 ConstantInstr* length = NULL; |
| 1855 if (call->is_known_list_constructor() && |
| 1856 LoadFieldInstr::IsFixedLengthArrayCid(call->Type()->ToCid())) { |
| 1857 length = call->ArgumentAt(1)->AsConstant(); |
| 1858 } |
| 1859 if (call->is_native_list_factory()) { |
| 1860 length = call->ArgumentAt(0)->AsConstant(); |
| 1861 } |
| 1862 if ((length != NULL) && length->value().IsSmi()) { |
| 1863 intptr_t known_length = Smi::Cast(length->value()).Value(); |
| 1864 return (known_length != field().guarded_list_length()) ? this : NULL; |
| 1865 } |
| 1866 } |
| 1818 return this; | 1867 return this; |
| 1819 } | 1868 } |
| 1820 | 1869 |
| 1821 if (field().is_nullable() && value()->Type()->IsNull()) { | 1870 if (field().is_nullable() && value()->Type()->IsNull()) { |
| 1822 return NULL; | 1871 return NULL; |
| 1823 } | 1872 } |
| 1824 | 1873 |
| 1825 const intptr_t cid = field().is_nullable() ? value()->Type()->ToNullableCid() | 1874 const intptr_t cid = field().is_nullable() ? value()->Type()->ToNullableCid() |
| 1826 : value()->Type()->ToCid(); | 1875 : value()->Type()->ToCid(); |
| 1827 if (field().guarded_cid() == cid) { | 1876 if (field().guarded_cid() == cid) { |
| (...skipping 1322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3150 case Token::kTRUNCDIV: return 0; | 3199 case Token::kTRUNCDIV: return 0; |
| 3151 case Token::kMOD: return 1; | 3200 case Token::kMOD: return 1; |
| 3152 default: UNIMPLEMENTED(); return -1; | 3201 default: UNIMPLEMENTED(); return -1; |
| 3153 } | 3202 } |
| 3154 } | 3203 } |
| 3155 | 3204 |
| 3156 | 3205 |
| 3157 #undef __ | 3206 #undef __ |
| 3158 | 3207 |
| 3159 } // namespace dart | 3208 } // namespace dart |
| OLD | NEW |