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

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

Issue 12041005: Optimize loads and stores to Int32Array and Uint32Array. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 11 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/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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698