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

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: 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
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 1326 matching lines...) Expand 10 before | Expand all | Expand 10 after
1337 // Reset value types if guarded_cid was used. 1337 // Reset value types if guarded_cid was used.
1338 for (Value::Iterator it(load->input_use_list()); 1338 for (Value::Iterator it(load->input_use_list());
1339 !it.Done(); 1339 !it.Done();
1340 it.Advance()) { 1340 it.Advance()) {
1341 it.Current()->SetReachingType(NULL); 1341 it.Current()->SetReachingType(NULL);
1342 } 1342 }
1343 } 1343 }
1344 } 1344 }
1345 1345
1346 1346
1347 void FlowGraphOptimizer::InlineArrayLengthGetter(InstanceCallInstr* call,
1348 intptr_t length_offset,
1349 bool is_immutable,
1350 MethodRecognizer::Kind kind) {
1351 AddReceiverCheck(call);
1352
1353 LoadFieldInstr* load = new LoadFieldInstr(
1354 new Value(call->ArgumentAt(0)),
1355 length_offset,
1356 Type::ZoneHandle(Type::SmiType()),
1357 is_immutable);
1358 load->set_result_cid(kSmiCid);
1359 load->set_recognized_kind(kind);
1360 ReplaceCall(call, load);
1361 }
1362
1363
1364 void FlowGraphOptimizer::InlineGrowableArrayCapacityGetter( 1347 void FlowGraphOptimizer::InlineGrowableArrayCapacityGetter(
1365 InstanceCallInstr* call) { 1348 InstanceCallInstr* call) {
1366 AddReceiverCheck(call); 1349 AddReceiverCheck(call);
1367 1350
1368 // TODO(srdjan): type of load should be GrowableObjectArrayType. 1351 // TODO(srdjan): type of load should be GrowableObjectArrayType.
1369 LoadFieldInstr* data_load = new LoadFieldInstr( 1352 LoadFieldInstr* data_load = new LoadFieldInstr(
1370 new Value(call->ArgumentAt(0)), 1353 new Value(call->ArgumentAt(0)),
1371 Array::data_offset(), 1354 Array::data_offset(),
1372 Type::ZoneHandle(Type::DynamicType())); 1355 Type::ZoneHandle(Type::DynamicType()));
1373 data_load->set_result_cid(kArrayCid); 1356 data_load->set_result_cid(kArrayCid);
(...skipping 19 matching lines...) Expand all
1393 new Value(str), 1376 new Value(str),
1394 String::length_offset(), 1377 String::length_offset(),
1395 Type::ZoneHandle(Type::SmiType()), 1378 Type::ZoneHandle(Type::SmiType()),
1396 is_immutable); 1379 is_immutable);
1397 load->set_result_cid(kSmiCid); 1380 load->set_result_cid(kSmiCid);
1398 load->set_recognized_kind(MethodRecognizer::kStringBaseLength); 1381 load->set_recognized_kind(MethodRecognizer::kStringBaseLength);
1399 return load; 1382 return load;
1400 } 1383 }
1401 1384
1402 1385
1403 void FlowGraphOptimizer::InlineStringLengthGetter(InstanceCallInstr* call) {
1404 AddReceiverCheck(call);
1405 LoadFieldInstr* load = BuildLoadStringLength(call->ArgumentAt(0));
1406 ReplaceCall(call, load);
1407 }
1408
1409
1410 void FlowGraphOptimizer::InlineStringIsEmptyGetter(InstanceCallInstr* call) { 1386 void FlowGraphOptimizer::InlineStringIsEmptyGetter(InstanceCallInstr* call) {
1411 AddReceiverCheck(call); 1387 AddReceiverCheck(call);
1412 1388
1413 LoadFieldInstr* load = BuildLoadStringLength(call->ArgumentAt(0)); 1389 LoadFieldInstr* load = BuildLoadStringLength(call->ArgumentAt(0));
1414 InsertBefore(call, load, NULL, Definition::kValue); 1390 InsertBefore(call, load, NULL, Definition::kValue);
1415 1391
1416 ConstantInstr* zero = flow_graph()->GetConstant(Smi::Handle(Smi::New(0))); 1392 ConstantInstr* zero = flow_graph()->GetConstant(Smi::Handle(Smi::New(0)));
1417 StrictCompareInstr* compare = 1393 StrictCompareInstr* compare =
1418 new StrictCompareInstr(call->token_pos(), 1394 new StrictCompareInstr(call->token_pos(),
1419 Token::kEQ_STRICT, 1395 Token::kEQ_STRICT,
1420 new Value(load), 1396 new Value(load),
1421 new Value(zero)); 1397 new Value(zero));
1422 ReplaceCall(call, compare); 1398 ReplaceCall(call, compare);
1423 } 1399 }
1424 1400
1425 1401
1426 void FlowGraphOptimizer::InlineObjectCid(InstanceCallInstr* call) { 1402 void FlowGraphOptimizer::InlineObjectCid(InstanceCallInstr* call) {
1427 LoadClassIdInstr* load = new LoadClassIdInstr(new Value(call->ArgumentAt(0))); 1403 LoadClassIdInstr* load = new LoadClassIdInstr(new Value(call->ArgumentAt(0)));
1428 ReplaceCall(call, load); 1404 ReplaceCall(call, load);
1429 } 1405 }
1430 1406
1431 1407
1432 static intptr_t OffsetForLengthGetter(MethodRecognizer::Kind kind) {
1433 switch (kind) {
1434 case MethodRecognizer::kObjectArrayLength:
1435 case MethodRecognizer::kImmutableArrayLength:
1436 return Array::length_offset();
1437 case MethodRecognizer::kTypedDataLength:
1438 // .length is defined in _TypedList which is the base class for internal
1439 // and external typed data.
1440 ASSERT(TypedData::length_offset() == ExternalTypedData::length_offset());
1441 return TypedData::length_offset();
1442 case MethodRecognizer::kGrowableArrayLength:
1443 return GrowableObjectArray::length_offset();
1444 default:
1445 UNREACHABLE();
1446 return 0;
1447 }
1448 }
1449
1450
1451 bool FlowGraphOptimizer::InlineFloat32x4Getter(InstanceCallInstr* call, 1408 bool FlowGraphOptimizer::InlineFloat32x4Getter(InstanceCallInstr* call,
1452 MethodRecognizer::Kind getter) { 1409 MethodRecognizer::Kind getter) {
1453 if (!ShouldInlineSimd()) { 1410 if (!ShouldInlineSimd()) {
1454 return false; 1411 return false;
1455 } 1412 }
1456 AddCheckClass(call->ArgumentAt(0), 1413 AddCheckClass(call->ArgumentAt(0),
1457 ICData::ZoneHandle( 1414 ICData::ZoneHandle(
1458 call->ic_data()->AsUnaryClassChecksForArgNr(0)), 1415 call->ic_data()->AsUnaryClassChecksForArgNr(0)),
1459 call->deopt_id(), 1416 call->deopt_id(),
1460 call->env(), 1417 call->env(),
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1590 // Not an implicit getter. 1547 // Not an implicit getter.
1591 MethodRecognizer::Kind recognized_kind = 1548 MethodRecognizer::Kind recognized_kind =
1592 MethodRecognizer::RecognizeKind(target); 1549 MethodRecognizer::RecognizeKind(target);
1593 1550
1594 // VM objects length getter. 1551 // VM objects length getter.
1595 switch (recognized_kind) { 1552 switch (recognized_kind) {
1596 case MethodRecognizer::kObjectCid: { 1553 case MethodRecognizer::kObjectCid: {
1597 InlineObjectCid(call); 1554 InlineObjectCid(call);
1598 return true; 1555 return true;
1599 } 1556 }
1600 case MethodRecognizer::kObjectArrayLength:
1601 case MethodRecognizer::kImmutableArrayLength:
1602 case MethodRecognizer::kTypedDataLength:
1603 case MethodRecognizer::kGrowableArrayLength: {
1604 if (!ic_data.HasOneTarget()) {
1605 // TODO(srdjan): Implement for mutiple targets.
1606 return false;
1607 }
1608 const bool is_immutable =
1609 (recognized_kind == MethodRecognizer::kObjectArrayLength) ||
1610 (recognized_kind == MethodRecognizer::kImmutableArrayLength) ||
1611 (recognized_kind == MethodRecognizer::kTypedDataLength);
1612 InlineArrayLengthGetter(call,
1613 OffsetForLengthGetter(recognized_kind),
1614 is_immutable,
1615 recognized_kind);
1616 return true;
1617 }
1618 case MethodRecognizer::kGrowableArrayCapacity: 1557 case MethodRecognizer::kGrowableArrayCapacity:
1619 InlineGrowableArrayCapacityGetter(call); 1558 InlineGrowableArrayCapacityGetter(call);
1620 return true; 1559 return true;
1621 case MethodRecognizer::kStringBaseLength:
1622 if (!ic_data.HasOneTarget()) {
1623 // Target is not only StringBase_get_length.
1624 return false;
1625 }
1626 InlineStringLengthGetter(call);
1627 return true;
1628 case MethodRecognizer::kStringBaseIsEmpty: 1560 case MethodRecognizer::kStringBaseIsEmpty:
1629 if (!ic_data.HasOneTarget()) { 1561 if (!ic_data.HasOneTarget()) {
1630 // Target is not only StringBase_get_isEmpty. 1562 // Target is not only StringBase_get_isEmpty.
1631 return false; 1563 return false;
1632 } 1564 }
1633 InlineStringIsEmptyGetter(call); 1565 InlineStringIsEmptyGetter(call);
1634 return true; 1566 return true;
1635 case MethodRecognizer::kFloat32x4ShuffleX: 1567 case MethodRecognizer::kFloat32x4ShuffleX:
1636 case MethodRecognizer::kFloat32x4ShuffleY: 1568 case MethodRecognizer::kFloat32x4ShuffleY:
1637 case MethodRecognizer::kFloat32x4ShuffleZ: 1569 case MethodRecognizer::kFloat32x4ShuffleZ:
1638 case MethodRecognizer::kFloat32x4ShuffleW: 1570 case MethodRecognizer::kFloat32x4ShuffleW:
1639 if (!ic_data.HasReceiverClassId(kFloat32x4Cid) || 1571 if (!ic_data.HasReceiverClassId(kFloat32x4Cid) ||
1640 !ic_data.HasOneTarget()) { 1572 !ic_data.HasOneTarget()) {
1641 return false; 1573 return false;
1642 } 1574 }
1643 return InlineFloat32x4Getter(call, recognized_kind); 1575 return InlineFloat32x4Getter(call, recognized_kind);
1644 case MethodRecognizer::kUint32x4GetFlagX: 1576 case MethodRecognizer::kUint32x4GetFlagX:
1645 case MethodRecognizer::kUint32x4GetFlagY: 1577 case MethodRecognizer::kUint32x4GetFlagY:
1646 case MethodRecognizer::kUint32x4GetFlagZ: 1578 case MethodRecognizer::kUint32x4GetFlagZ:
1647 case MethodRecognizer::kUint32x4GetFlagW: { 1579 case MethodRecognizer::kUint32x4GetFlagW: {
1648 if (!ic_data.HasReceiverClassId(kUint32x4Cid) || 1580 if (!ic_data.HasReceiverClassId(kUint32x4Cid) ||
1649 !ic_data.HasOneTarget()) { 1581 !ic_data.HasOneTarget()) {
1650 return false; 1582 return false;
1651 } 1583 }
1652 return InlineUint32x4Getter(call, recognized_kind); 1584 return InlineUint32x4Getter(call, recognized_kind);
1653 } 1585 }
1654 default: 1586 default:
1655 ASSERT(recognized_kind == MethodRecognizer::kUnknown); 1587 break;
1656 } 1588 }
1657 return false; 1589 return false;
1658 } 1590 }
1659 1591
1660 1592
1661 LoadIndexedInstr* FlowGraphOptimizer::BuildStringCodeUnitAt( 1593 LoadIndexedInstr* FlowGraphOptimizer::BuildStringCodeUnitAt(
1662 InstanceCallInstr* call, 1594 InstanceCallInstr* call,
1663 intptr_t cid) { 1595 intptr_t cid) {
1664 Definition* str = call->ArgumentAt(0); 1596 Definition* str = call->ArgumentAt(0);
1665 Definition* index = call->ArgumentAt(1); 1597 Definition* index = call->ArgumentAt(1);
(...skipping 5743 matching lines...) Expand 10 before | Expand all | Expand 10 after
7409 } 7341 }
7410 7342
7411 // Insert materializations at environment uses. 7343 // Insert materializations at environment uses.
7412 for (intptr_t i = 0; i < exits.length(); i++) { 7344 for (intptr_t i = 0; i < exits.length(); i++) {
7413 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); 7345 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields);
7414 } 7346 }
7415 } 7347 }
7416 7348
7417 7349
7418 } // namespace dart 7350 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698