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/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 579 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 590 case kUint8ClampedArrayCid: | 590 case kUint8ClampedArrayCid: |
| 591 case kInt16ArrayCid: | 591 case kInt16ArrayCid: |
| 592 case kUint16ArrayCid: | 592 case kUint16ArrayCid: |
| 593 // Check that value is always smi. | 593 // Check that value is always smi. |
| 594 value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2); | 594 value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2); |
| 595 if ((value_check.NumberOfChecks() != 1) || | 595 if ((value_check.NumberOfChecks() != 1) || |
| 596 (value_check.GetReceiverClassIdAt(0) != kSmiCid)) { | 596 (value_check.GetReceiverClassIdAt(0) != kSmiCid)) { |
| 597 return false; | 597 return false; |
| 598 } | 598 } |
| 599 break; | 599 break; |
| 600 | 600 case kInt32ArrayCid: |
| 601 case kUint32ArrayCid: { | |
| 602 // Check if elements fit into a smi or the platform supports unboxed | |
| 603 // mints. | |
| 604 if ((kSmiBits < 32) && !FlowGraphCompiler::SupportsUnboxedMints()) { | |
| 605 return false; | |
| 606 } | |
| 607 // Check that value is always smi (or mint, if the platform has unboxed | |
| 608 // mints (ia32 with at least SSE 4.1) | |
|
Kevin Millikin (Google)
2013/01/21 15:16:01
The lack of period (and the unbalanced parens
Florian Schneider
2013/01/21 16:03:25
Done.
| |
| 609 value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2); | |
|
Kevin Millikin (Google)
2013/01/21 15:16:01
ArgNr? Srsly?
| |
| 610 for (intptr_t i = 0; i < value_check.NumberOfChecks(); i++) { | |
| 611 intptr_t cid = value_check.GetReceiverClassIdAt(i); | |
| 612 if (FlowGraphCompiler::SupportsUnboxedMints()) { | |
| 613 if ((cid != kSmiCid) && (cid != kMintCid)) { | |
| 614 return false; | |
| 615 } | |
| 616 } else if (cid != kSmiCid) { | |
| 617 return false; | |
| 618 } | |
| 619 } | |
| 620 break; | |
| 621 } | |
| 601 case kFloat32ArrayCid: | 622 case kFloat32ArrayCid: |
| 602 case kFloat64ArrayCid: { | 623 case kFloat64ArrayCid: { |
| 603 // Check that value is always double. | 624 // Check that value is always double. |
| 604 value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2); | 625 value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2); |
| 605 if ((value_check.NumberOfChecks() != 1) || | 626 if ((value_check.NumberOfChecks() != 1) || |
| 606 (value_check.GetReceiverClassIdAt(0) != kDoubleCid)) { | 627 (value_check.GetReceiverClassIdAt(0) != kDoubleCid)) { |
| 607 return false; | 628 return false; |
| 608 } | 629 } |
| 609 break; | 630 break; |
| 610 } | 631 } |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 638 InsertBefore(call, load_type_args, NULL, Definition::kValue); | 659 InsertBefore(call, load_type_args, NULL, Definition::kValue); |
| 639 instantiator = array->Copy(); | 660 instantiator = array->Copy(); |
| 640 type_args = new Value(load_type_args); | 661 type_args = new Value(load_type_args); |
| 641 break; | 662 break; |
| 642 } | 663 } |
| 643 case kInt8ArrayCid: | 664 case kInt8ArrayCid: |
| 644 case kUint8ArrayCid: | 665 case kUint8ArrayCid: |
| 645 case kUint8ClampedArrayCid: | 666 case kUint8ClampedArrayCid: |
| 646 case kInt16ArrayCid: | 667 case kInt16ArrayCid: |
| 647 case kUint16ArrayCid: | 668 case kUint16ArrayCid: |
| 669 case kInt32ArrayCid: | |
| 670 case kUint32ArrayCid: | |
| 648 ASSERT(value_type.IsIntType()); | 671 ASSERT(value_type.IsIntType()); |
| 649 // Fall through. | 672 // Fall through. |
| 650 case kFloat32ArrayCid: | 673 case kFloat32ArrayCid: |
| 651 case kFloat64ArrayCid: { | 674 case kFloat64ArrayCid: { |
| 652 instantiator = new Value(flow_graph_->constant_null()); | 675 instantiator = new Value(flow_graph_->constant_null()); |
| 653 type_args = new Value(flow_graph_->constant_null()); | 676 type_args = new Value(flow_graph_->constant_null()); |
| 654 ASSERT((class_id != kFloat32ArrayCid && class_id != kFloat64ArrayCid) || | 677 ASSERT((class_id != kFloat32ArrayCid && class_id != kFloat64ArrayCid) || |
| 655 value_type.IsDoubleType()); | 678 value_type.IsDoubleType()); |
| 656 ASSERT(value_type.IsInstantiated()); | 679 ASSERT(value_type.IsInstantiated()); |
| 657 break; | 680 break; |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 670 InsertBefore(call, assert_value, NULL, Definition::kValue); | 693 InsertBefore(call, assert_value, NULL, Definition::kValue); |
| 671 } | 694 } |
| 672 | 695 |
| 673 Value* array = NULL; | 696 Value* array = NULL; |
| 674 Value* index = NULL; | 697 Value* index = NULL; |
| 675 intptr_t array_cid = PrepareIndexedOp(call, class_id, &array, &index); | 698 intptr_t array_cid = PrepareIndexedOp(call, class_id, &array, &index); |
| 676 Value* value = call->ArgumentAt(2)->value(); | 699 Value* value = call->ArgumentAt(2)->value(); |
| 677 // Check if store barrier is needed. | 700 // Check if store barrier is needed. |
| 678 bool needs_store_barrier = true; | 701 bool needs_store_barrier = true; |
| 679 if (!value_check.IsNull()) { | 702 if (!value_check.IsNull()) { |
| 680 ASSERT(value_check.NumberOfChecks() == 1); | 703 needs_store_barrier = false; |
| 681 if (value_check.GetReceiverClassIdAt(0) == kSmiCid) { | 704 if (value_check.NumberOfChecks() == 1 && |
| 705 value_check.GetReceiverClassIdAt(0) == kSmiCid) { | |
| 682 InsertBefore(call, | 706 InsertBefore(call, |
| 683 new CheckSmiInstr(value->Copy(), call->deopt_id()), | 707 new CheckSmiInstr(value->Copy(), call->deopt_id()), |
| 684 call->env(), | 708 call->env(), |
| 685 Definition::kEffect); | 709 Definition::kEffect); |
| 686 needs_store_barrier = false; | |
| 687 } else { | 710 } else { |
| 688 ASSERT(value_check.GetReceiverClassIdAt(0) == kDoubleCid); | |
| 689 InsertBefore(call, | 711 InsertBefore(call, |
| 690 new CheckClassInstr(value->Copy(), | 712 new CheckClassInstr(value->Copy(), |
| 691 call->deopt_id(), | 713 call->deopt_id(), |
| 692 value_check), | 714 value_check), |
| 693 call->env(), | 715 call->env(), |
| 694 Definition::kEffect); | 716 Definition::kEffect); |
| 695 needs_store_barrier = false; | |
| 696 } | 717 } |
| 697 } | 718 } |
| 698 | 719 |
| 699 Definition* array_op = | 720 Definition* array_op = |
| 700 new StoreIndexedInstr(array, index, value, | 721 new StoreIndexedInstr(array, index, value, |
| 701 needs_store_barrier, array_cid, call->deopt_id()); | 722 needs_store_barrier, array_cid, call->deopt_id()); |
| 702 call->ReplaceWith(array_op, current_iterator()); | 723 call->ReplaceWith(array_op, current_iterator()); |
| 703 RemovePushArguments(call); | 724 RemovePushArguments(call); |
| 704 return true; | 725 return true; |
| 705 } | 726 } |
| 706 | 727 |
| 707 | 728 |
| 708 | 729 |
| 709 bool FlowGraphOptimizer::TryReplaceWithLoadIndexed(InstanceCallInstr* call) { | 730 bool FlowGraphOptimizer::TryReplaceWithLoadIndexed(InstanceCallInstr* call) { |
| 710 const intptr_t class_id = ReceiverClassId(call); | 731 const intptr_t class_id = ReceiverClassId(call); |
| 711 switch (class_id) { | 732 switch (class_id) { |
| 712 case kArrayCid: | 733 case kArrayCid: |
| 713 case kImmutableArrayCid: | 734 case kImmutableArrayCid: |
| 714 case kGrowableObjectArrayCid: | 735 case kGrowableObjectArrayCid: |
| 715 case kFloat32ArrayCid: | 736 case kFloat32ArrayCid: |
| 716 case kFloat64ArrayCid: | 737 case kFloat64ArrayCid: |
| 717 case kInt8ArrayCid: | 738 case kInt8ArrayCid: |
| 718 case kUint8ArrayCid: | 739 case kUint8ArrayCid: |
| 719 case kUint8ClampedArrayCid: | 740 case kUint8ClampedArrayCid: |
| 720 case kExternalUint8ArrayCid: | 741 case kExternalUint8ArrayCid: |
| 721 case kInt16ArrayCid: | 742 case kInt16ArrayCid: |
| 722 case kUint16ArrayCid: | 743 case kUint16ArrayCid: |
| 723 // Acceptable load index classes. | 744 break; |
| 745 case kInt32ArrayCid: | |
| 746 case kUint32ArrayCid: | |
| 747 // Check if elements fit into a smi or the platform supports unboxed | |
| 748 // mints. | |
| 749 if ((kSmiBits < 32) && !FlowGraphCompiler::SupportsUnboxedMints()) { | |
| 750 return false; | |
| 751 } | |
| 724 break; | 752 break; |
| 725 default: | 753 default: |
| 726 return false; | 754 return false; |
| 727 } | 755 } |
| 728 Value* array = NULL; | 756 Value* array = NULL; |
| 729 Value* index = NULL; | 757 Value* index = NULL; |
| 730 intptr_t array_cid = PrepareIndexedOp(call, class_id, &array, &index); | 758 intptr_t array_cid = PrepareIndexedOp(call, class_id, &array, &index); |
| 731 Definition* array_op = new LoadIndexedInstr(array, index, array_cid); | 759 Definition* array_op = new LoadIndexedInstr(array, index, array_cid); |
| 732 call->ReplaceWith(array_op, current_iterator()); | 760 call->ReplaceWith(array_op, current_iterator()); |
| 733 RemovePushArguments(call); | 761 RemovePushArguments(call); |
| (...skipping 3808 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4542 | 4570 |
| 4543 if (FLAG_trace_constant_propagation) { | 4571 if (FLAG_trace_constant_propagation) { |
| 4544 OS::Print("\n==== After constant propagation ====\n"); | 4572 OS::Print("\n==== After constant propagation ====\n"); |
| 4545 FlowGraphPrinter printer(*graph_); | 4573 FlowGraphPrinter printer(*graph_); |
| 4546 printer.PrintBlocks(); | 4574 printer.PrintBlocks(); |
| 4547 } | 4575 } |
| 4548 } | 4576 } |
| 4549 | 4577 |
| 4550 | 4578 |
| 4551 } // namespace dart | 4579 } // namespace dart |
| OLD | NEW |