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/cpu.h" | 9 #include "vm/cpu.h" |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 1346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1357 } | 1357 } |
1358 | 1358 |
1359 if (array_cid == kTypedDataFloat32ArrayCid) { | 1359 if (array_cid == kTypedDataFloat32ArrayCid) { |
1360 stored_value = | 1360 stored_value = |
1361 new(I) DoubleToFloatInstr( | 1361 new(I) DoubleToFloatInstr( |
1362 new(I) Value(stored_value), call->deopt_id()); | 1362 new(I) Value(stored_value), call->deopt_id()); |
1363 cursor = flow_graph()->AppendTo(cursor, | 1363 cursor = flow_graph()->AppendTo(cursor, |
1364 stored_value, | 1364 stored_value, |
1365 NULL, | 1365 NULL, |
1366 FlowGraph::kValue); | 1366 FlowGraph::kValue); |
1367 } else if (array_cid == kTypedDataInt32ArrayCid) { | |
1368 stored_value = new(I) UnboxInt32Instr( | |
1369 new(I) Value(stored_value), | |
1370 call->deopt_id()); | |
1371 stored_value->AsUnboxIntN()->mark_truncating(); | |
1372 cursor = flow_graph()->AppendTo(cursor, | |
1373 stored_value, | |
1374 call->env(), | |
1375 FlowGraph::kValue); | |
1376 } else if (array_cid == kTypedDataUint32ArrayCid) { | |
1377 stored_value = new(I) UnboxUint32Instr( | |
1378 new(I) Value(stored_value), | |
1379 call->deopt_id()); | |
1380 ASSERT(stored_value->AsUnboxIntN()->is_truncating()); | |
1381 cursor = flow_graph()->AppendTo(cursor, | |
1382 stored_value, | |
1383 call->env(), | |
1384 FlowGraph::kValue); | |
1367 } | 1385 } |
1368 | 1386 |
1387 | |
Florian Schneider
2014/09/11 09:38:53
Remove extra \n.
Vyacheslav Egorov (Google)
2014/09/11 11:49:17
Done.
| |
1369 const intptr_t index_scale = Instance::ElementSizeFor(array_cid); | 1388 const intptr_t index_scale = Instance::ElementSizeFor(array_cid); |
1370 *last = new(I) StoreIndexedInstr(new(I) Value(array), | 1389 *last = new(I) StoreIndexedInstr(new(I) Value(array), |
1371 new(I) Value(index), | 1390 new(I) Value(index), |
1372 new(I) Value(stored_value), | 1391 new(I) Value(stored_value), |
1373 needs_store_barrier, | 1392 needs_store_barrier, |
1374 index_scale, | 1393 index_scale, |
1375 array_cid, | 1394 array_cid, |
1376 call->deopt_id(), | 1395 call->deopt_id(), |
1377 call->token_pos()); | 1396 call->token_pos()); |
1378 flow_graph()->AppendTo(cursor, | 1397 flow_graph()->AppendTo(cursor, |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1439 case MethodRecognizer::kInt16ArraySetIndexed: | 1458 case MethodRecognizer::kInt16ArraySetIndexed: |
1440 case MethodRecognizer::kUint16ArraySetIndexed: | 1459 case MethodRecognizer::kUint16ArraySetIndexed: |
1441 if (!ArgIsAlways(kSmiCid, ic_data, 2)) { | 1460 if (!ArgIsAlways(kSmiCid, ic_data, 2)) { |
1442 return false; | 1461 return false; |
1443 } | 1462 } |
1444 value_check = ic_data.AsUnaryClassChecksForArgNr(2); | 1463 value_check = ic_data.AsUnaryClassChecksForArgNr(2); |
1445 return InlineSetIndexed(kind, target, call, receiver, token_pos, | 1464 return InlineSetIndexed(kind, target, call, receiver, token_pos, |
1446 &ic_data, value_check, entry, last); | 1465 &ic_data, value_check, entry, last); |
1447 case MethodRecognizer::kInt32ArraySetIndexed: | 1466 case MethodRecognizer::kInt32ArraySetIndexed: |
1448 case MethodRecognizer::kUint32ArraySetIndexed: | 1467 case MethodRecognizer::kUint32ArraySetIndexed: |
1449 if (!CanUnboxInt32()) { | |
1450 return false; | |
1451 } | |
1452 // Check that value is always smi or mint, if the platform has unboxed | 1468 // Check that value is always smi or mint, if the platform has unboxed |
1453 // mints (ia32 with at least SSE 4.1). | 1469 // mints (ia32 with at least SSE 4.1). |
Florian Schneider
2014/09/11 09:38:53
This comment is now out of date.
Vyacheslav Egorov (Google)
2014/09/11 11:49:17
Done.
| |
1454 value_check = ic_data.AsUnaryClassChecksForArgNr(2); | 1470 value_check = ic_data.AsUnaryClassChecksForArgNr(2); |
1455 if (FlowGraphCompiler::SupportsUnboxedMints()) { | 1471 if (!HasOnlySmiOrMint(value_check)) { |
1456 if (!HasOnlySmiOrMint(value_check)) { | |
1457 return false; | |
1458 } | |
1459 } else if (!HasOnlyOneSmi(value_check)) { | |
1460 return false; | 1472 return false; |
1461 } | 1473 } |
1462 return InlineSetIndexed(kind, target, call, receiver, token_pos, | 1474 return InlineSetIndexed(kind, target, call, receiver, token_pos, |
1463 &ic_data, value_check, entry, last); | 1475 &ic_data, value_check, entry, last); |
1464 case MethodRecognizer::kFloat32ArraySetIndexed: | 1476 case MethodRecognizer::kFloat32ArraySetIndexed: |
1465 case MethodRecognizer::kFloat64ArraySetIndexed: | 1477 case MethodRecognizer::kFloat64ArraySetIndexed: |
1466 if (!CanUnboxDouble()) { | 1478 if (!CanUnboxDouble()) { |
1467 return false; | 1479 return false; |
1468 } | 1480 } |
1469 // Check that value is always double. | 1481 // Check that value is always double. |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1563 ic_data, entry, last); | 1575 ic_data, entry, last); |
1564 case MethodRecognizer::kByteArrayBaseSetInt16: | 1576 case MethodRecognizer::kByteArrayBaseSetInt16: |
1565 return InlineByteArrayViewStore(target, call, receiver, receiver_cid, | 1577 return InlineByteArrayViewStore(target, call, receiver, receiver_cid, |
1566 kTypedDataInt16ArrayCid, | 1578 kTypedDataInt16ArrayCid, |
1567 ic_data, entry, last); | 1579 ic_data, entry, last); |
1568 case MethodRecognizer::kByteArrayBaseSetUint16: | 1580 case MethodRecognizer::kByteArrayBaseSetUint16: |
1569 return InlineByteArrayViewStore(target, call, receiver, receiver_cid, | 1581 return InlineByteArrayViewStore(target, call, receiver, receiver_cid, |
1570 kTypedDataUint16ArrayCid, | 1582 kTypedDataUint16ArrayCid, |
1571 ic_data, entry, last); | 1583 ic_data, entry, last); |
1572 case MethodRecognizer::kByteArrayBaseSetInt32: | 1584 case MethodRecognizer::kByteArrayBaseSetInt32: |
1573 if (!CanUnboxInt32()) { | |
1574 return false; | |
1575 } | |
1576 return InlineByteArrayViewStore(target, call, receiver, receiver_cid, | 1585 return InlineByteArrayViewStore(target, call, receiver, receiver_cid, |
1577 kTypedDataInt32ArrayCid, | 1586 kTypedDataInt32ArrayCid, |
1578 ic_data, entry, last); | 1587 ic_data, entry, last); |
1579 case MethodRecognizer::kByteArrayBaseSetUint32: | 1588 case MethodRecognizer::kByteArrayBaseSetUint32: |
1580 if (!CanUnboxInt32()) { | |
1581 return false; | |
1582 } | |
1583 return InlineByteArrayViewStore(target, call, receiver, receiver_cid, | 1589 return InlineByteArrayViewStore(target, call, receiver, receiver_cid, |
1584 kTypedDataUint32ArrayCid, | 1590 kTypedDataUint32ArrayCid, |
1585 ic_data, entry, last); | 1591 ic_data, entry, last); |
1586 case MethodRecognizer::kByteArrayBaseSetFloat32: | 1592 case MethodRecognizer::kByteArrayBaseSetFloat32: |
1587 if (!CanUnboxDouble()) { | 1593 if (!CanUnboxDouble()) { |
1588 return false; | 1594 return false; |
1589 } | 1595 } |
1590 return InlineByteArrayViewStore(target, call, receiver, receiver_cid, | 1596 return InlineByteArrayViewStore(target, call, receiver, receiver_cid, |
1591 kTypedDataFloat32ArrayCid, | 1597 kTypedDataFloat32ArrayCid, |
1592 ic_data, entry, last); | 1598 ic_data, entry, last); |
(...skipping 2122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3715 Object::empty_array(), // Dummy args. descr. | 3721 Object::empty_array(), // Dummy args. descr. |
3716 Isolate::kNoDeoptId, | 3722 Isolate::kNoDeoptId, |
3717 1); | 3723 1); |
3718 value_check.AddReceiverCheck(kSmiCid, target); | 3724 value_check.AddReceiverCheck(kSmiCid, target); |
3719 break; | 3725 break; |
3720 } | 3726 } |
3721 case kTypedDataInt32ArrayCid: | 3727 case kTypedDataInt32ArrayCid: |
3722 case kTypedDataUint32ArrayCid: | 3728 case kTypedDataUint32ArrayCid: |
3723 // Prevent excessive deoptimization, assume full 32 bits used, and therefore | 3729 // Prevent excessive deoptimization, assume full 32 bits used, and therefore |
3724 // generate Mint on 32-bit architectures. | 3730 // generate Mint on 32-bit architectures. |
3725 if (kSmiBits >= 32) { | 3731 if (kSmiBits >= 32) { |
3726 value_check = ICData::New(flow_graph_->parsed_function().function(), | 3732 value_check = ICData::New(flow_graph_->parsed_function().function(), |
3727 i_call->function_name(), | 3733 i_call->function_name(), |
3728 Object::empty_array(), // Dummy args. descr. | 3734 Object::empty_array(), // Dummy args. descr. |
3729 Isolate::kNoDeoptId, | 3735 Isolate::kNoDeoptId, |
3730 1); | 3736 1); |
3731 value_check.AddReceiverCheck(kSmiCid, target); | 3737 value_check.AddReceiverCheck(kSmiCid, target); |
3732 } | 3738 } |
3733 break; | 3739 break; |
3734 case kTypedDataFloat32ArrayCid: | 3740 case kTypedDataFloat32ArrayCid: |
3735 case kTypedDataFloat64ArrayCid: { | 3741 case kTypedDataFloat64ArrayCid: { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3773 call); | 3779 call); |
3774 } | 3780 } |
3775 | 3781 |
3776 if (view_cid == kTypedDataFloat32ArrayCid) { | 3782 if (view_cid == kTypedDataFloat32ArrayCid) { |
3777 stored_value = new(I) DoubleToFloatInstr( | 3783 stored_value = new(I) DoubleToFloatInstr( |
3778 new(I) Value(stored_value), call->deopt_id()); | 3784 new(I) Value(stored_value), call->deopt_id()); |
3779 cursor = flow_graph()->AppendTo(cursor, | 3785 cursor = flow_graph()->AppendTo(cursor, |
3780 stored_value, | 3786 stored_value, |
3781 NULL, | 3787 NULL, |
3782 FlowGraph::kValue); | 3788 FlowGraph::kValue); |
3789 } else if (view_cid == kTypedDataInt32ArrayCid) { | |
3790 stored_value = new(I) UnboxInt32Instr( | |
3791 new(I) Value(stored_value), | |
3792 call->deopt_id()); | |
3793 stored_value->AsUnboxIntN()->mark_truncating(); | |
3794 cursor = flow_graph()->AppendTo(cursor, | |
3795 stored_value, | |
3796 call->env(), | |
3797 FlowGraph::kValue); | |
3798 } else if (view_cid == kTypedDataUint32ArrayCid) { | |
3799 stored_value = new(I) UnboxUint32Instr( | |
3800 new(I) Value(stored_value), | |
3801 call->deopt_id()); | |
3802 ASSERT(stored_value->AsUnboxIntN()->is_truncating()); | |
3803 cursor = flow_graph()->AppendTo(cursor, | |
3804 stored_value, | |
3805 call->env(), | |
3806 FlowGraph::kValue); | |
3783 } | 3807 } |
3784 | 3808 |
3785 StoreBarrierType needs_store_barrier = kNoStoreBarrier; | 3809 StoreBarrierType needs_store_barrier = kNoStoreBarrier; |
3786 *last = new(I) StoreIndexedInstr(new(I) Value(array), | 3810 *last = new(I) StoreIndexedInstr(new(I) Value(array), |
3787 new(I) Value(index), | 3811 new(I) Value(index), |
3788 new(I) Value(stored_value), | 3812 new(I) Value(stored_value), |
3789 needs_store_barrier, | 3813 needs_store_barrier, |
3790 1, // Index scale | 3814 1, // Index scale |
3791 view_cid, | 3815 view_cid, |
3792 call->deopt_id(), | 3816 call->deopt_id(), |
(...skipping 4483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8276 SetValue(instr, non_constant_); | 8300 SetValue(instr, non_constant_); |
8277 break; | 8301 break; |
8278 } | 8302 } |
8279 result = result.CheckAndCanonicalize(NULL); | 8303 result = result.CheckAndCanonicalize(NULL); |
8280 ASSERT(!result.IsNull()); | 8304 ASSERT(!result.IsNull()); |
8281 SetValue(instr, result); | 8305 SetValue(instr, result); |
8282 break; | 8306 break; |
8283 } | 8307 } |
8284 case Token::kSHL: | 8308 case Token::kSHL: |
8285 case Token::kSHR: | 8309 case Token::kSHR: |
8286 if (left.IsSmi() && right.IsSmi()) { | 8310 if (left.IsSmi() && |
8311 right.IsSmi() && | |
8312 (Smi::Cast(right).Value() >= 0)) { | |
8287 Instance& result = Integer::ZoneHandle(I, | 8313 Instance& result = Integer::ZoneHandle(I, |
8288 Smi::Cast(left_int).ShiftOp(op_kind, Smi::Cast(right_int))); | 8314 Smi::Cast(left_int).ShiftOp(op_kind, Smi::Cast(right_int))); |
8289 if (result.IsNull()) { | |
8290 // TODO(regis): A bigint operation is required. Invoke dart? | |
8291 // Punt for now. | |
8292 SetValue(instr, non_constant_); | |
8293 break; | |
8294 } | |
8295 result = result.CheckAndCanonicalize(NULL); | 8315 result = result.CheckAndCanonicalize(NULL); |
8296 ASSERT(!result.IsNull()); | 8316 ASSERT(!result.IsNull()); |
8297 SetValue(instr, result); | 8317 SetValue(instr, result); |
8298 } else { | 8318 } else { |
8299 SetValue(instr, non_constant_); | 8319 SetValue(instr, non_constant_); |
8300 } | 8320 } |
8301 break; | 8321 break; |
8302 case Token::kBIT_AND: | 8322 case Token::kBIT_AND: |
8303 case Token::kBIT_OR: | 8323 case Token::kBIT_OR: |
8304 case Token::kBIT_XOR: { | 8324 case Token::kBIT_XOR: { |
(...skipping 1770 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10075 | 10095 |
10076 // Insert materializations at environment uses. | 10096 // Insert materializations at environment uses. |
10077 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { | 10097 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { |
10078 CreateMaterializationAt( | 10098 CreateMaterializationAt( |
10079 exits_collector_.exits()[i], alloc, alloc->cls(), *slots); | 10099 exits_collector_.exits()[i], alloc, alloc->cls(), *slots); |
10080 } | 10100 } |
10081 } | 10101 } |
10082 | 10102 |
10083 | 10103 |
10084 } // namespace dart | 10104 } // namespace dart |
OLD | NEW |