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

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

Issue 22839003: Polymorphic inlining for some recognized methods in the optimizing compiler. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: fixed modulo performance regression Created 7 years, 4 months 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) 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/dart_entry.h" 9 #include "vm/dart_entry.h"
10 #include "vm/flow_graph_builder.h" 10 #include "vm/flow_graph_builder.h"
(...skipping 1372 matching lines...) Expand 10 before | Expand all | Expand 10 after
1383 // Reset value types if guarded_cid was used. 1383 // Reset value types if guarded_cid was used.
1384 for (Value::Iterator it(load->input_use_list()); 1384 for (Value::Iterator it(load->input_use_list());
1385 !it.Done(); 1385 !it.Done();
1386 it.Advance()) { 1386 it.Advance()) {
1387 it.Current()->SetReachingType(NULL); 1387 it.Current()->SetReachingType(NULL);
1388 } 1388 }
1389 } 1389 }
1390 } 1390 }
1391 1391
1392 1392
1393 void FlowGraphOptimizer::InlineArrayLengthGetter(InstanceCallInstr* call,
1394 intptr_t length_offset,
1395 bool is_immutable,
1396 MethodRecognizer::Kind kind) {
1397 AddReceiverCheck(call);
1398
1399 LoadFieldInstr* load = new LoadFieldInstr(
1400 new Value(call->ArgumentAt(0)),
1401 length_offset,
1402 Type::ZoneHandle(Type::SmiType()),
1403 is_immutable);
1404 load->set_result_cid(kSmiCid);
1405 load->set_recognized_kind(kind);
1406 ReplaceCall(call, load);
1407 }
1408
1409
1410 void FlowGraphOptimizer::InlineGrowableArrayCapacityGetter( 1393 void FlowGraphOptimizer::InlineGrowableArrayCapacityGetter(
1411 InstanceCallInstr* call) { 1394 InstanceCallInstr* call) {
1412 AddReceiverCheck(call); 1395 AddReceiverCheck(call);
1413 1396
1414 // TODO(srdjan): type of load should be GrowableObjectArrayType. 1397 // TODO(srdjan): type of load should be GrowableObjectArrayType.
1415 LoadFieldInstr* data_load = new LoadFieldInstr( 1398 LoadFieldInstr* data_load = new LoadFieldInstr(
1416 new Value(call->ArgumentAt(0)), 1399 new Value(call->ArgumentAt(0)),
1417 Array::data_offset(), 1400 Array::data_offset(),
1418 Type::ZoneHandle(Type::DynamicType())); 1401 Type::ZoneHandle(Type::DynamicType()));
1419 data_load->set_result_cid(kArrayCid); 1402 data_load->set_result_cid(kArrayCid);
(...skipping 19 matching lines...) Expand all
1439 new Value(str), 1422 new Value(str),
1440 String::length_offset(), 1423 String::length_offset(),
1441 Type::ZoneHandle(Type::SmiType()), 1424 Type::ZoneHandle(Type::SmiType()),
1442 is_immutable); 1425 is_immutable);
1443 load->set_result_cid(kSmiCid); 1426 load->set_result_cid(kSmiCid);
1444 load->set_recognized_kind(MethodRecognizer::kStringBaseLength); 1427 load->set_recognized_kind(MethodRecognizer::kStringBaseLength);
1445 return load; 1428 return load;
1446 } 1429 }
1447 1430
1448 1431
1449 void FlowGraphOptimizer::InlineStringLengthGetter(InstanceCallInstr* call) {
1450 AddReceiverCheck(call);
1451 LoadFieldInstr* load = BuildLoadStringLength(call->ArgumentAt(0));
1452 ReplaceCall(call, load);
1453 }
1454
1455
1456 void FlowGraphOptimizer::InlineStringIsEmptyGetter(InstanceCallInstr* call) { 1432 void FlowGraphOptimizer::InlineStringIsEmptyGetter(InstanceCallInstr* call) {
1457 AddReceiverCheck(call); 1433 AddReceiverCheck(call);
1458 1434
1459 LoadFieldInstr* load = BuildLoadStringLength(call->ArgumentAt(0)); 1435 LoadFieldInstr* load = BuildLoadStringLength(call->ArgumentAt(0));
1460 InsertBefore(call, load, NULL, Definition::kValue); 1436 InsertBefore(call, load, NULL, Definition::kValue);
1461 1437
1462 ConstantInstr* zero = flow_graph()->GetConstant(Smi::Handle(Smi::New(0))); 1438 ConstantInstr* zero = flow_graph()->GetConstant(Smi::Handle(Smi::New(0)));
1463 StrictCompareInstr* compare = 1439 StrictCompareInstr* compare =
1464 new StrictCompareInstr(call->token_pos(), 1440 new StrictCompareInstr(call->token_pos(),
1465 Token::kEQ_STRICT, 1441 Token::kEQ_STRICT,
1466 new Value(load), 1442 new Value(load),
1467 new Value(zero)); 1443 new Value(zero));
1468 ReplaceCall(call, compare); 1444 ReplaceCall(call, compare);
1469 } 1445 }
1470 1446
1471 1447
1472 void FlowGraphOptimizer::InlineObjectCid(InstanceCallInstr* call) { 1448 void FlowGraphOptimizer::InlineObjectCid(InstanceCallInstr* call) {
1473 LoadClassIdInstr* load = new LoadClassIdInstr(new Value(call->ArgumentAt(0))); 1449 LoadClassIdInstr* load = new LoadClassIdInstr(new Value(call->ArgumentAt(0)));
1474 ReplaceCall(call, load); 1450 ReplaceCall(call, load);
1475 } 1451 }
1476 1452
1477 1453
1478 static intptr_t OffsetForLengthGetter(MethodRecognizer::Kind kind) {
1479 switch (kind) {
1480 case MethodRecognizer::kObjectArrayLength:
1481 case MethodRecognizer::kImmutableArrayLength:
1482 return Array::length_offset();
1483 case MethodRecognizer::kTypedDataLength:
1484 // .length is defined in _TypedList which is the base class for internal
1485 // and external typed data.
1486 ASSERT(TypedData::length_offset() == ExternalTypedData::length_offset());
1487 return TypedData::length_offset();
1488 case MethodRecognizer::kGrowableArrayLength:
1489 return GrowableObjectArray::length_offset();
1490 default:
1491 UNREACHABLE();
1492 return 0;
1493 }
1494 }
1495
1496
1497 bool FlowGraphOptimizer::InlineFloat32x4Getter(InstanceCallInstr* call, 1454 bool FlowGraphOptimizer::InlineFloat32x4Getter(InstanceCallInstr* call,
1498 MethodRecognizer::Kind getter) { 1455 MethodRecognizer::Kind getter) {
1499 if (!ShouldInlineSimd()) { 1456 if (!ShouldInlineSimd()) {
1500 return false; 1457 return false;
1501 } 1458 }
1502 AddCheckClass(call->ArgumentAt(0), 1459 AddCheckClass(call->ArgumentAt(0),
1503 ICData::ZoneHandle( 1460 ICData::ZoneHandle(
1504 call->ic_data()->AsUnaryClassChecksForArgNr(0)), 1461 call->ic_data()->AsUnaryClassChecksForArgNr(0)),
1505 call->deopt_id(), 1462 call->deopt_id(),
1506 call->env(), 1463 call->env(),
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1671 // Not an implicit getter. 1628 // Not an implicit getter.
1672 MethodRecognizer::Kind recognized_kind = 1629 MethodRecognizer::Kind recognized_kind =
1673 MethodRecognizer::RecognizeKind(target); 1630 MethodRecognizer::RecognizeKind(target);
1674 1631
1675 // VM objects length getter. 1632 // VM objects length getter.
1676 switch (recognized_kind) { 1633 switch (recognized_kind) {
1677 case MethodRecognizer::kObjectCid: { 1634 case MethodRecognizer::kObjectCid: {
1678 InlineObjectCid(call); 1635 InlineObjectCid(call);
1679 return true; 1636 return true;
1680 } 1637 }
1681 case MethodRecognizer::kObjectArrayLength:
1682 case MethodRecognizer::kImmutableArrayLength:
1683 case MethodRecognizer::kTypedDataLength:
1684 case MethodRecognizer::kGrowableArrayLength: {
1685 if (!ic_data.HasOneTarget()) {
1686 // TODO(srdjan): Implement for mutiple targets.
1687 return false;
1688 }
1689 const bool is_immutable =
1690 (recognized_kind == MethodRecognizer::kObjectArrayLength) ||
1691 (recognized_kind == MethodRecognizer::kImmutableArrayLength) ||
1692 (recognized_kind == MethodRecognizer::kTypedDataLength);
1693 InlineArrayLengthGetter(call,
1694 OffsetForLengthGetter(recognized_kind),
1695 is_immutable,
1696 recognized_kind);
1697 return true;
1698 }
1699 case MethodRecognizer::kGrowableArrayCapacity: 1638 case MethodRecognizer::kGrowableArrayCapacity:
1700 InlineGrowableArrayCapacityGetter(call); 1639 InlineGrowableArrayCapacityGetter(call);
1701 return true; 1640 return true;
1702 case MethodRecognizer::kStringBaseLength:
1703 if (!ic_data.HasOneTarget()) {
1704 // Target is not only StringBase_get_length.
1705 return false;
1706 }
1707 InlineStringLengthGetter(call);
1708 return true;
1709 case MethodRecognizer::kStringBaseIsEmpty: 1641 case MethodRecognizer::kStringBaseIsEmpty:
1710 if (!ic_data.HasOneTarget()) { 1642 if (!ic_data.HasOneTarget()) {
1711 // Target is not only StringBase_get_isEmpty. 1643 // Target is not only StringBase_get_isEmpty.
1712 return false; 1644 return false;
1713 } 1645 }
1714 InlineStringIsEmptyGetter(call); 1646 InlineStringIsEmptyGetter(call);
1715 return true; 1647 return true;
1716 case MethodRecognizer::kFloat32x4ShuffleX: 1648 case MethodRecognizer::kFloat32x4ShuffleX:
1717 case MethodRecognizer::kFloat32x4ShuffleY: 1649 case MethodRecognizer::kFloat32x4ShuffleY:
1718 case MethodRecognizer::kFloat32x4ShuffleZ: 1650 case MethodRecognizer::kFloat32x4ShuffleZ:
1719 case MethodRecognizer::kFloat32x4ShuffleW: 1651 case MethodRecognizer::kFloat32x4ShuffleW:
1720 case MethodRecognizer::kFloat32x4GetSignMask: 1652 case MethodRecognizer::kFloat32x4GetSignMask:
1721 if (!ic_data.HasReceiverClassId(kFloat32x4Cid) || 1653 if (!ic_data.HasReceiverClassId(kFloat32x4Cid) ||
1722 !ic_data.HasOneTarget()) { 1654 !ic_data.HasOneTarget()) {
1723 return false; 1655 return false;
1724 } 1656 }
1725 return InlineFloat32x4Getter(call, recognized_kind); 1657 return InlineFloat32x4Getter(call, recognized_kind);
1726 case MethodRecognizer::kUint32x4GetFlagX: 1658 case MethodRecognizer::kUint32x4GetFlagX:
1727 case MethodRecognizer::kUint32x4GetFlagY: 1659 case MethodRecognizer::kUint32x4GetFlagY:
1728 case MethodRecognizer::kUint32x4GetFlagZ: 1660 case MethodRecognizer::kUint32x4GetFlagZ:
1729 case MethodRecognizer::kUint32x4GetFlagW: 1661 case MethodRecognizer::kUint32x4GetFlagW:
1730 case MethodRecognizer::kUint32x4GetSignMask: { 1662 case MethodRecognizer::kUint32x4GetSignMask: {
1731 if (!ic_data.HasReceiverClassId(kUint32x4Cid) || 1663 if (!ic_data.HasReceiverClassId(kUint32x4Cid) ||
1732 !ic_data.HasOneTarget()) { 1664 !ic_data.HasOneTarget()) {
1733 return false; 1665 return false;
1734 } 1666 }
1735 return InlineUint32x4Getter(call, recognized_kind); 1667 return InlineUint32x4Getter(call, recognized_kind);
1736 } 1668 }
1737 default: 1669 default:
1738 ASSERT(recognized_kind == MethodRecognizer::kUnknown); 1670 break;
1739 } 1671 }
1740 return false; 1672 return false;
1741 } 1673 }
1742 1674
1743 1675
1744 LoadIndexedInstr* FlowGraphOptimizer::BuildStringCodeUnitAt( 1676 LoadIndexedInstr* FlowGraphOptimizer::BuildStringCodeUnitAt(
1745 InstanceCallInstr* call, 1677 InstanceCallInstr* call,
1746 intptr_t cid) { 1678 intptr_t cid) {
1747 Definition* str = call->ArgumentAt(0); 1679 Definition* str = call->ArgumentAt(0);
1748 Definition* index = call->ArgumentAt(1); 1680 Definition* index = call->ArgumentAt(1);
(...skipping 5823 matching lines...) Expand 10 before | Expand all | Expand 10 after
7572 } 7504 }
7573 7505
7574 // Insert materializations at environment uses. 7506 // Insert materializations at environment uses.
7575 for (intptr_t i = 0; i < exits.length(); i++) { 7507 for (intptr_t i = 0; i < exits.length(); i++) {
7576 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); 7508 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields);
7577 } 7509 }
7578 } 7510 }
7579 7511
7580 7512
7581 } // namespace dart 7513 } // 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