Chromium Code Reviews| 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/aot_optimizer.h" | 5 #include "vm/aot_optimizer.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/branch_optimizer.h" | 8 #include "vm/branch_optimizer.h" |
| 9 #include "vm/cha.h" | 9 #include "vm/cha.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 1547 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1558 | 1558 |
| 1559 | 1559 |
| 1560 // TODO(srdjan): Apply optimizations as in ReplaceWithInstanceOf (TestCids). | 1560 // TODO(srdjan): Apply optimizations as in ReplaceWithInstanceOf (TestCids). |
| 1561 void AotOptimizer::ReplaceWithTypeCast(InstanceCallInstr* call) { | 1561 void AotOptimizer::ReplaceWithTypeCast(InstanceCallInstr* call) { |
| 1562 ASSERT(Token::IsTypeCastOperator(call->token_kind())); | 1562 ASSERT(Token::IsTypeCastOperator(call->token_kind())); |
| 1563 Definition* left = call->ArgumentAt(0); | 1563 Definition* left = call->ArgumentAt(0); |
| 1564 Definition* type_args = call->ArgumentAt(1); | 1564 Definition* type_args = call->ArgumentAt(1); |
| 1565 const AbstractType& type = | 1565 const AbstractType& type = |
| 1566 AbstractType::Cast(call->ArgumentAt(2)->AsConstant()->value()); | 1566 AbstractType::Cast(call->ArgumentAt(2)->AsConstant()->value()); |
| 1567 ASSERT(!type.IsMalformedOrMalbounded()); | 1567 ASSERT(!type.IsMalformedOrMalbounded()); |
| 1568 | |
| 1569 if (TypeCheckAsClassEquality(type)) { | |
| 1570 LoadClassIdInstr* left_cid = new (Z) LoadClassIdInstr(new (Z) Value(left)); | |
| 1571 InsertBefore(call, left_cid, NULL, FlowGraph::kValue); | |
| 1572 const intptr_t type_cid = Class::ZoneHandle(Z, type.type_class()).id(); | |
| 1573 ConstantInstr* cid = | |
| 1574 flow_graph()->GetConstant(Smi::ZoneHandle(Z, Smi::New(type_cid))); | |
| 1575 ConstantInstr* pos = flow_graph()->GetConstant( | |
| 1576 Smi::ZoneHandle(Z, Smi::New(call->token_pos().Pos()))); | |
| 1577 | |
| 1578 ZoneGrowableArray<PushArgumentInstr*>* args = | |
| 1579 new (Z) ZoneGrowableArray<PushArgumentInstr*>(5); | |
| 1580 PushArgumentInstr* arg = new (Z) PushArgumentInstr(new (Z) Value(pos)); | |
| 1581 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | |
| 1582 args->Add(arg); | |
| 1583 arg = new (Z) PushArgumentInstr(new (Z) Value(left)); | |
| 1584 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | |
| 1585 args->Add(arg); | |
| 1586 arg = new (Z) | |
| 1587 PushArgumentInstr(new (Z) Value(flow_graph()->GetConstant(type))); | |
| 1588 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | |
| 1589 args->Add(arg); | |
| 1590 arg = new (Z) PushArgumentInstr(new (Z) Value(left_cid)); | |
| 1591 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | |
| 1592 args->Add(arg); | |
| 1593 arg = new (Z) PushArgumentInstr(new (Z) Value(cid)); | |
| 1594 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | |
| 1595 args->Add(arg); | |
| 1596 | |
| 1597 const Library& dart_internal = Library::Handle(Z, Library::CoreLibrary()); | |
| 1598 const String& target_name = Symbols::_classIdEqualsAssert(); | |
| 1599 const Function& target = Function::ZoneHandle( | |
| 1600 Z, dart_internal.LookupFunctionAllowPrivate(target_name)); | |
| 1601 ASSERT(!target.IsNull()); | |
| 1602 ASSERT(target.IsRecognized()); | |
| 1603 ASSERT(target.always_inline()); | |
| 1604 | |
| 1605 StaticCallInstr* new_call = | |
| 1606 new (Z) StaticCallInstr(call->token_pos(), target, | |
| 1607 Object::null_array(), // argument_names | |
| 1608 args, call->deopt_id()); | |
| 1609 Environment* copy = | |
| 1610 call->env()->DeepCopy(Z, call->env()->Length() - call->ArgumentCount()); | |
| 1611 for (intptr_t i = 0; i < args->length(); ++i) { | |
| 1612 copy->PushValue(new (Z) Value((*args)[i]->value()->definition())); | |
| 1613 } | |
| 1614 call->RemoveEnvironment(); | |
| 1615 ReplaceCall(call, new_call); | |
| 1616 copy->DeepCopyTo(Z, new_call); | |
|
siva
2017/04/13 17:01:04
Maybe not for this CL but in a follow up CL, this
| |
| 1617 return; | |
| 1618 } | |
| 1619 | |
| 1620 if (precompiler_ != NULL) { | |
| 1621 TypeRangeCache* cache = precompiler_->type_range_cache(); | |
| 1622 intptr_t lower_limit, upper_limit; | |
| 1623 if (cache != NULL && | |
| 1624 cache->InstanceOfHasClassRange(type, &lower_limit, &upper_limit)) { | |
| 1625 // left.instanceof(type) => | |
| 1626 // _classRangeCheck(left.cid, lower_limit, upper_limit) | |
| 1627 | |
| 1628 LoadClassIdInstr* left_cid = | |
| 1629 new (Z) LoadClassIdInstr(new (Z) Value(left)); | |
| 1630 InsertBefore(call, left_cid, NULL, FlowGraph::kValue); | |
| 1631 ConstantInstr* lower_cid = | |
| 1632 flow_graph()->GetConstant(Smi::ZoneHandle(Z, Smi::New(lower_limit))); | |
| 1633 ConstantInstr* upper_cid = | |
| 1634 flow_graph()->GetConstant(Smi::ZoneHandle(Z, Smi::New(upper_limit))); | |
| 1635 ConstantInstr* pos = flow_graph()->GetConstant( | |
| 1636 Smi::ZoneHandle(Z, Smi::New(call->token_pos().Pos()))); | |
| 1637 | |
| 1638 ZoneGrowableArray<PushArgumentInstr*>* args = | |
| 1639 new (Z) ZoneGrowableArray<PushArgumentInstr*>(6); | |
| 1640 PushArgumentInstr* arg = new (Z) PushArgumentInstr(new (Z) Value(pos)); | |
| 1641 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | |
| 1642 args->Add(arg); | |
| 1643 arg = new (Z) PushArgumentInstr(new (Z) Value(left)); | |
| 1644 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | |
| 1645 args->Add(arg); | |
| 1646 arg = new (Z) | |
| 1647 PushArgumentInstr(new (Z) Value(flow_graph()->GetConstant(type))); | |
| 1648 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | |
| 1649 args->Add(arg); | |
| 1650 arg = new (Z) PushArgumentInstr(new (Z) Value(left_cid)); | |
| 1651 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | |
| 1652 args->Add(arg); | |
| 1653 arg = new (Z) PushArgumentInstr(new (Z) Value(lower_cid)); | |
| 1654 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | |
| 1655 args->Add(arg); | |
| 1656 arg = new (Z) PushArgumentInstr(new (Z) Value(upper_cid)); | |
| 1657 InsertBefore(call, arg, NULL, FlowGraph::kEffect); | |
| 1658 args->Add(arg); | |
| 1659 | |
| 1660 const Library& dart_internal = Library::Handle(Z, Library::CoreLibrary()); | |
| 1661 const String& target_name = Symbols::_classRangeAssert(); | |
| 1662 const Function& target = Function::ZoneHandle( | |
| 1663 Z, dart_internal.LookupFunctionAllowPrivate(target_name)); | |
| 1664 ASSERT(!target.IsNull()); | |
| 1665 ASSERT(target.IsRecognized()); | |
| 1666 ASSERT(target.always_inline()); | |
| 1667 | |
| 1668 StaticCallInstr* new_call = | |
| 1669 new (Z) StaticCallInstr(call->token_pos(), target, | |
| 1670 Object::null_array(), // argument_names | |
| 1671 args, call->deopt_id()); | |
| 1672 Environment* copy = call->env()->DeepCopy( | |
| 1673 Z, call->env()->Length() - call->ArgumentCount()); | |
| 1674 for (intptr_t i = 0; i < args->length(); ++i) { | |
| 1675 copy->PushValue(new (Z) Value((*args)[i]->value()->definition())); | |
| 1676 } | |
| 1677 call->RemoveEnvironment(); | |
| 1678 ReplaceCall(call, new_call); | |
| 1679 copy->DeepCopyTo(Z, new_call); | |
| 1680 return; | |
| 1681 } | |
| 1682 } | |
| 1683 | |
| 1568 const ICData& unary_checks = | 1684 const ICData& unary_checks = |
| 1569 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks()); | 1685 ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks()); |
| 1570 const intptr_t number_of_checks = unary_checks.NumberOfChecks(); | 1686 const intptr_t number_of_checks = unary_checks.NumberOfChecks(); |
| 1571 if (number_of_checks > 0 && number_of_checks <= FLAG_max_polymorphic_checks) { | 1687 if (number_of_checks > 0 && number_of_checks <= FLAG_max_polymorphic_checks) { |
| 1572 ZoneGrowableArray<intptr_t>* results = | 1688 ZoneGrowableArray<intptr_t>* results = |
| 1573 new (Z) ZoneGrowableArray<intptr_t>(number_of_checks * 2); | 1689 new (Z) ZoneGrowableArray<intptr_t>(number_of_checks * 2); |
| 1574 const Bool& as_bool = | 1690 const Bool& as_bool = |
| 1575 Bool::ZoneHandle(Z, InstanceOfAsBool(unary_checks, type, results)); | 1691 Bool::ZoneHandle(Z, InstanceOfAsBool(unary_checks, type, results)); |
| 1576 if (as_bool.raw() == Bool::True().raw()) { | 1692 if (as_bool.raw() == Bool::True().raw()) { |
| 1577 // Guard against repeated speculative inlining. | 1693 // Guard against repeated speculative inlining. |
| (...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2132 FlowGraph::kEffect); | 2248 FlowGraph::kEffect); |
| 2133 current_iterator()->RemoveCurrentFromGraph(); | 2249 current_iterator()->RemoveCurrentFromGraph(); |
| 2134 } | 2250 } |
| 2135 } | 2251 } |
| 2136 } | 2252 } |
| 2137 } | 2253 } |
| 2138 | 2254 |
| 2139 #endif // DART_PRECOMPILER | 2255 #endif // DART_PRECOMPILER |
| 2140 | 2256 |
| 2141 } // namespace dart | 2257 } // namespace dart |
| OLD | NEW |