| 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/flow_graph_builder.h" | 9 #include "vm/flow_graph_builder.h" |
| 10 #include "vm/flow_graph_compiler.h" | 10 #include "vm/flow_graph_compiler.h" |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 356 if ((constant != NULL) && constant->value().IsSmi()) { | 356 if ((constant != NULL) && constant->value().IsSmi()) { |
| 357 const double dbl_val = Smi::Cast(constant->value()).AsDoubleValue(); | 357 const double dbl_val = Smi::Cast(constant->value()).AsDoubleValue(); |
| 358 const Double& dbl_obj = | 358 const Double& dbl_obj = |
| 359 Double::ZoneHandle(Double::New(dbl_val, Heap::kOld)); | 359 Double::ZoneHandle(Double::New(dbl_val, Heap::kOld)); |
| 360 ConstantInstr* double_const = new ConstantInstr(dbl_obj); | 360 ConstantInstr* double_const = new ConstantInstr(dbl_obj); |
| 361 InsertBefore(insert_before, double_const, NULL, Definition::kValue); | 361 InsertBefore(insert_before, double_const, NULL, Definition::kValue); |
| 362 converted = new UnboxDoubleInstr(new Value(double_const), deopt_id); | 362 converted = new UnboxDoubleInstr(new Value(double_const), deopt_id); |
| 363 } else { | 363 } else { |
| 364 converted = new UnboxDoubleInstr(use->CopyWithType(), deopt_id); | 364 converted = new UnboxDoubleInstr(use->CopyWithType(), deopt_id); |
| 365 } | 365 } |
| 366 } else if ((from == kTagged) && (to == kUnboxedFloat32x4)) { |
| 367 ASSERT((deopt_target != NULL) || |
| 368 (use->Type()->ToCid() == kFloat32x4Cid)); |
| 369 const intptr_t deopt_id = (deopt_target != NULL) ? |
| 370 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; |
| 371 converted = new UnboxFloat32x4Instr(use->CopyWithType(), deopt_id); |
| 372 } else if ((from == kUnboxedFloat32x4) && (to == kTagged)) { |
| 373 converted = new BoxFloat32x4Instr(use->CopyWithType(), NULL); |
| 366 } | 374 } |
| 367 ASSERT(converted != NULL); | 375 ASSERT(converted != NULL); |
| 368 use->BindTo(converted); | 376 use->BindTo(converted); |
| 369 InsertBefore(insert_before, converted, use->instruction()->env(), | 377 InsertBefore(insert_before, converted, use->instruction()->env(), |
| 370 Definition::kValue); | 378 Definition::kValue); |
| 371 } | 379 } |
| 372 | 380 |
| 373 | 381 |
| 374 void FlowGraphOptimizer::InsertConversionsFor(Definition* def) { | 382 void FlowGraphOptimizer::InsertConversionsFor(Definition* def) { |
| 375 const Representation from_rep = def->representation(); | 383 const Representation from_rep = def->representation(); |
| (...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 873 bool FlowGraphOptimizer::TryReplaceWithLoadIndexed(InstanceCallInstr* call) { | 881 bool FlowGraphOptimizer::TryReplaceWithLoadIndexed(InstanceCallInstr* call) { |
| 874 const intptr_t class_id = ReceiverClassId(call); | 882 const intptr_t class_id = ReceiverClassId(call); |
| 875 // Set deopt_id to a valid id if the LoadIndexedInstr can cause deopt. | 883 // Set deopt_id to a valid id if the LoadIndexedInstr can cause deopt. |
| 876 intptr_t deopt_id = Isolate::kNoDeoptId; | 884 intptr_t deopt_id = Isolate::kNoDeoptId; |
| 877 switch (class_id) { | 885 switch (class_id) { |
| 878 case kArrayCid: | 886 case kArrayCid: |
| 879 case kImmutableArrayCid: | 887 case kImmutableArrayCid: |
| 880 case kGrowableObjectArrayCid: | 888 case kGrowableObjectArrayCid: |
| 881 case kTypedDataFloat32ArrayCid: | 889 case kTypedDataFloat32ArrayCid: |
| 882 case kTypedDataFloat64ArrayCid: | 890 case kTypedDataFloat64ArrayCid: |
| 891 case kTypedDataFloat32x4ArrayCid: |
| 883 case kTypedDataInt8ArrayCid: | 892 case kTypedDataInt8ArrayCid: |
| 884 case kTypedDataUint8ArrayCid: | 893 case kTypedDataUint8ArrayCid: |
| 885 case kTypedDataUint8ClampedArrayCid: | 894 case kTypedDataUint8ClampedArrayCid: |
| 886 case kExternalTypedDataUint8ArrayCid: | 895 case kExternalTypedDataUint8ArrayCid: |
| 887 case kExternalTypedDataUint8ClampedArrayCid: | 896 case kExternalTypedDataUint8ClampedArrayCid: |
| 888 case kTypedDataInt16ArrayCid: | 897 case kTypedDataInt16ArrayCid: |
| 889 case kTypedDataUint16ArrayCid: | 898 case kTypedDataUint16ArrayCid: |
| 890 break; | 899 break; |
| 891 case kTypedDataInt32ArrayCid: | 900 case kTypedDataInt32ArrayCid: |
| 892 case kTypedDataUint32ArrayCid: { | 901 case kTypedDataUint32ArrayCid: { |
| (...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1463 case kTypedDataUint8ArrayCid: | 1472 case kTypedDataUint8ArrayCid: |
| 1464 case kExternalTypedDataUint8ArrayCid: | 1473 case kExternalTypedDataUint8ArrayCid: |
| 1465 case kTypedDataUint8ClampedArrayCid: | 1474 case kTypedDataUint8ClampedArrayCid: |
| 1466 case kExternalTypedDataUint8ClampedArrayCid: | 1475 case kExternalTypedDataUint8ClampedArrayCid: |
| 1467 case kTypedDataInt16ArrayCid: | 1476 case kTypedDataInt16ArrayCid: |
| 1468 case kTypedDataUint16ArrayCid: | 1477 case kTypedDataUint16ArrayCid: |
| 1469 case kTypedDataInt32ArrayCid: | 1478 case kTypedDataInt32ArrayCid: |
| 1470 case kTypedDataUint32ArrayCid: | 1479 case kTypedDataUint32ArrayCid: |
| 1471 case kTypedDataFloat32ArrayCid: | 1480 case kTypedDataFloat32ArrayCid: |
| 1472 case kTypedDataFloat64ArrayCid: | 1481 case kTypedDataFloat64ArrayCid: |
| 1482 case kTypedDataFloat32x4ArrayCid: |
| 1473 return true; | 1483 return true; |
| 1474 default: | 1484 default: |
| 1475 return false; | 1485 return false; |
| 1476 } | 1486 } |
| 1477 } | 1487 } |
| 1478 | 1488 |
| 1479 | 1489 |
| 1480 // Inline only simple, frequently called core library methods. | 1490 // Inline only simple, frequently called core library methods. |
| 1481 bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { | 1491 bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { |
| 1482 ASSERT(call->HasICData()); | 1492 ASSERT(call->HasICData()); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1596 call, class_ids[0], kTypedDataInt32ArrayCid); | 1606 call, class_ids[0], kTypedDataInt32ArrayCid); |
| 1597 case MethodRecognizer::kByteArrayBaseGetUint32: | 1607 case MethodRecognizer::kByteArrayBaseGetUint32: |
| 1598 return BuildByteArrayViewLoad( | 1608 return BuildByteArrayViewLoad( |
| 1599 call, class_ids[0], kTypedDataUint32ArrayCid); | 1609 call, class_ids[0], kTypedDataUint32ArrayCid); |
| 1600 case MethodRecognizer::kByteArrayBaseGetFloat32: | 1610 case MethodRecognizer::kByteArrayBaseGetFloat32: |
| 1601 return BuildByteArrayViewLoad( | 1611 return BuildByteArrayViewLoad( |
| 1602 call, class_ids[0], kTypedDataFloat32ArrayCid); | 1612 call, class_ids[0], kTypedDataFloat32ArrayCid); |
| 1603 case MethodRecognizer::kByteArrayBaseGetFloat64: | 1613 case MethodRecognizer::kByteArrayBaseGetFloat64: |
| 1604 return BuildByteArrayViewLoad( | 1614 return BuildByteArrayViewLoad( |
| 1605 call, class_ids[0], kTypedDataFloat64ArrayCid); | 1615 call, class_ids[0], kTypedDataFloat64ArrayCid); |
| 1616 case MethodRecognizer::kByteArrayBaseGetFloat32x4: |
| 1617 return BuildByteArrayViewLoad( |
| 1618 call, class_ids[0], kTypedDataFloat32x4ArrayCid); |
| 1606 | 1619 |
| 1607 // ByteArray setters. | 1620 // ByteArray setters. |
| 1608 case MethodRecognizer::kByteArrayBaseSetInt8: | 1621 case MethodRecognizer::kByteArrayBaseSetInt8: |
| 1609 return BuildByteArrayViewStore( | 1622 return BuildByteArrayViewStore( |
| 1610 call, class_ids[0], kTypedDataInt8ArrayCid); | 1623 call, class_ids[0], kTypedDataInt8ArrayCid); |
| 1611 case MethodRecognizer::kByteArrayBaseSetUint8: | 1624 case MethodRecognizer::kByteArrayBaseSetUint8: |
| 1612 return BuildByteArrayViewStore( | 1625 return BuildByteArrayViewStore( |
| 1613 call, class_ids[0], kTypedDataUint8ArrayCid); | 1626 call, class_ids[0], kTypedDataUint8ArrayCid); |
| 1614 case MethodRecognizer::kByteArrayBaseSetInt16: | 1627 case MethodRecognizer::kByteArrayBaseSetInt16: |
| 1615 return BuildByteArrayViewStore( | 1628 return BuildByteArrayViewStore( |
| 1616 call, class_ids[0], kTypedDataInt16ArrayCid); | 1629 call, class_ids[0], kTypedDataInt16ArrayCid); |
| 1617 case MethodRecognizer::kByteArrayBaseSetUint16: | 1630 case MethodRecognizer::kByteArrayBaseSetUint16: |
| 1618 return BuildByteArrayViewStore( | 1631 return BuildByteArrayViewStore( |
| 1619 call, class_ids[0], kTypedDataUint16ArrayCid); | 1632 call, class_ids[0], kTypedDataUint16ArrayCid); |
| 1620 case MethodRecognizer::kByteArrayBaseSetInt32: | 1633 case MethodRecognizer::kByteArrayBaseSetInt32: |
| 1621 return BuildByteArrayViewStore( | 1634 return BuildByteArrayViewStore( |
| 1622 call, class_ids[0], kTypedDataInt32ArrayCid); | 1635 call, class_ids[0], kTypedDataInt32ArrayCid); |
| 1623 case MethodRecognizer::kByteArrayBaseSetUint32: | 1636 case MethodRecognizer::kByteArrayBaseSetUint32: |
| 1624 return BuildByteArrayViewStore( | 1637 return BuildByteArrayViewStore( |
| 1625 call, class_ids[0], kTypedDataUint32ArrayCid); | 1638 call, class_ids[0], kTypedDataUint32ArrayCid); |
| 1626 case MethodRecognizer::kByteArrayBaseSetFloat32: | 1639 case MethodRecognizer::kByteArrayBaseSetFloat32: |
| 1627 return BuildByteArrayViewStore( | 1640 return BuildByteArrayViewStore( |
| 1628 call, class_ids[0], kTypedDataFloat32ArrayCid); | 1641 call, class_ids[0], kTypedDataFloat32ArrayCid); |
| 1629 case MethodRecognizer::kByteArrayBaseSetFloat64: | 1642 case MethodRecognizer::kByteArrayBaseSetFloat64: |
| 1630 return BuildByteArrayViewStore( | 1643 return BuildByteArrayViewStore( |
| 1631 call, class_ids[0], kTypedDataFloat64ArrayCid); | 1644 call, class_ids[0], kTypedDataFloat64ArrayCid); |
| 1645 case MethodRecognizer::kByteArrayBaseSetFloat32x4: |
| 1646 return BuildByteArrayViewStore( |
| 1647 call, class_ids[0], kTypedDataFloat32x4ArrayCid); |
| 1632 default: | 1648 default: |
| 1633 // Unsupported method. | 1649 // Unsupported method. |
| 1634 return false; | 1650 return false; |
| 1635 } | 1651 } |
| 1636 } | 1652 } |
| 1637 return false; | 1653 return false; |
| 1638 } | 1654 } |
| 1639 | 1655 |
| 1640 | 1656 |
| 1641 bool FlowGraphOptimizer::BuildByteArrayViewLoad( | 1657 bool FlowGraphOptimizer::BuildByteArrayViewLoad( |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1704 case kTypedDataFloat32ArrayCid: | 1720 case kTypedDataFloat32ArrayCid: |
| 1705 case kTypedDataFloat64ArrayCid: { | 1721 case kTypedDataFloat64ArrayCid: { |
| 1706 // Check that value is always double. | 1722 // Check that value is always double. |
| 1707 value_check = ICData::New(Function::Handle(), | 1723 value_check = ICData::New(Function::Handle(), |
| 1708 String::Handle(), | 1724 String::Handle(), |
| 1709 Isolate::kNoDeoptId, | 1725 Isolate::kNoDeoptId, |
| 1710 1); | 1726 1); |
| 1711 value_check.AddReceiverCheck(kDoubleCid, Function::Handle()); | 1727 value_check.AddReceiverCheck(kDoubleCid, Function::Handle()); |
| 1712 break; | 1728 break; |
| 1713 } | 1729 } |
| 1730 case kTypedDataFloat32x4ArrayCid: { |
| 1731 // Check that value is always Float32x4. |
| 1732 value_check = ICData::New(Function::Handle(), |
| 1733 String::Handle(), |
| 1734 Isolate::kNoDeoptId, |
| 1735 1); |
| 1736 value_check.AddReceiverCheck(kFloat32x4Cid, Function::Handle()); |
| 1737 break; |
| 1738 } |
| 1714 default: | 1739 default: |
| 1715 // Array cids are already checked in the caller. | 1740 // Array cids are already checked in the caller. |
| 1716 UNREACHABLE(); | 1741 UNREACHABLE(); |
| 1717 return NULL; | 1742 return NULL; |
| 1718 } | 1743 } |
| 1719 | 1744 |
| 1720 Definition* index = call->ArgumentAt(1); | 1745 Definition* index = call->ArgumentAt(1); |
| 1721 Definition* stored_value = call->ArgumentAt(2); | 1746 Definition* stored_value = call->ArgumentAt(2); |
| 1722 if (!value_check.IsNull()) { | 1747 if (!value_check.IsNull()) { |
| 1723 AddCheckClass(stored_value, value_check, call->deopt_id(), call->env(), | 1748 AddCheckClass(stored_value, value_check, call->deopt_id(), call->env(), |
| (...skipping 2623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4347 const Object& value = instr->value()->definition()->constant_value(); | 4372 const Object& value = instr->value()->definition()->constant_value(); |
| 4348 if (IsNonConstant(value)) { | 4373 if (IsNonConstant(value)) { |
| 4349 SetValue(instr, non_constant_); | 4374 SetValue(instr, non_constant_); |
| 4350 } else if (IsConstant(value)) { | 4375 } else if (IsConstant(value)) { |
| 4351 // TODO(kmillikin): Handle conversion. | 4376 // TODO(kmillikin): Handle conversion. |
| 4352 SetValue(instr, non_constant_); | 4377 SetValue(instr, non_constant_); |
| 4353 } | 4378 } |
| 4354 } | 4379 } |
| 4355 | 4380 |
| 4356 | 4381 |
| 4382 void ConstantPropagator::VisitUnboxFloat32x4(UnboxFloat32x4Instr* instr) { |
| 4383 const Object& value = instr->value()->definition()->constant_value(); |
| 4384 if (IsNonConstant(value)) { |
| 4385 SetValue(instr, non_constant_); |
| 4386 } else if (IsConstant(value)) { |
| 4387 // TODO(kmillikin): Handle conversion. |
| 4388 SetValue(instr, non_constant_); |
| 4389 } |
| 4390 } |
| 4391 |
| 4392 |
| 4393 void ConstantPropagator::VisitBoxFloat32x4(BoxFloat32x4Instr* instr) { |
| 4394 const Object& value = instr->value()->definition()->constant_value(); |
| 4395 if (IsNonConstant(value)) { |
| 4396 SetValue(instr, non_constant_); |
| 4397 } else if (IsConstant(value)) { |
| 4398 // TODO(kmillikin): Handle conversion. |
| 4399 SetValue(instr, non_constant_); |
| 4400 } |
| 4401 } |
| 4402 |
| 4403 |
| 4357 void ConstantPropagator::Analyze() { | 4404 void ConstantPropagator::Analyze() { |
| 4358 GraphEntryInstr* entry = graph_->graph_entry(); | 4405 GraphEntryInstr* entry = graph_->graph_entry(); |
| 4359 reachable_->Add(entry->preorder_number()); | 4406 reachable_->Add(entry->preorder_number()); |
| 4360 block_worklist_.Add(entry); | 4407 block_worklist_.Add(entry); |
| 4361 | 4408 |
| 4362 while (true) { | 4409 while (true) { |
| 4363 if (block_worklist_.is_empty()) { | 4410 if (block_worklist_.is_empty()) { |
| 4364 if (definition_worklist_.is_empty()) break; | 4411 if (definition_worklist_.is_empty()) break; |
| 4365 Definition* definition = definition_worklist_.RemoveLast(); | 4412 Definition* definition = definition_worklist_.RemoveLast(); |
| 4366 definition_marks_->Remove(definition->ssa_temp_index()); | 4413 definition_marks_->Remove(definition->ssa_temp_index()); |
| (...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4743 if (changed) { | 4790 if (changed) { |
| 4744 // We may have changed the block order and the dominator tree. | 4791 // We may have changed the block order and the dominator tree. |
| 4745 flow_graph->DiscoverBlocks(); | 4792 flow_graph->DiscoverBlocks(); |
| 4746 GrowableArray<BitVector*> dominance_frontier; | 4793 GrowableArray<BitVector*> dominance_frontier; |
| 4747 flow_graph->ComputeDominators(&dominance_frontier); | 4794 flow_graph->ComputeDominators(&dominance_frontier); |
| 4748 } | 4795 } |
| 4749 } | 4796 } |
| 4750 | 4797 |
| 4751 | 4798 |
| 4752 } // namespace dart | 4799 } // namespace dart |
| OLD | NEW |