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

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

Issue 10823022: Improve static type propagation. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 5 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
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/object.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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/intermediate_language.h" 5 #include "vm/intermediate_language.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/dart_entry.h" 8 #include "vm/dart_entry.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"
11 #include "vm/locations.h" 11 #include "vm/locations.h"
12 #include "vm/object.h" 12 #include "vm/object.h"
13 #include "vm/os.h" 13 #include "vm/os.h"
14 #include "vm/scopes.h" 14 #include "vm/scopes.h"
15 #include "vm/stub_code.h" 15 #include "vm/stub_code.h"
16 #include "vm/symbols.h" 16 #include "vm/symbols.h"
17 17
18 namespace dart { 18 namespace dart {
19 19
20 DECLARE_FLAG(bool, enable_type_checks);
21
22
20 MethodRecognizer::Kind MethodRecognizer::RecognizeKind( 23 MethodRecognizer::Kind MethodRecognizer::RecognizeKind(
21 const Function& function) { 24 const Function& function) {
22 // Only core library methods can be recognized. 25 // Only core library methods can be recognized.
23 const Library& core_lib = Library::Handle(Library::CoreLibrary()); 26 const Library& core_lib = Library::Handle(Library::CoreLibrary());
24 const Library& core_impl_lib = Library::Handle(Library::CoreImplLibrary()); 27 const Library& core_impl_lib = Library::Handle(Library::CoreImplLibrary());
25 const Class& function_class = Class::Handle(function.owner()); 28 const Class& function_class = Class::Handle(function.owner());
26 if ((function_class.library() != core_lib.raw()) && 29 if ((function_class.library() != core_lib.raw()) &&
27 (function_class.library() != core_impl_lib.raw())) { 30 (function_class.library() != core_impl_lib.raw())) {
28 return kUnknown; 31 return kUnknown;
29 } 32 }
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
320 Value* PhiInstr::InputAt(intptr_t i) const { 323 Value* PhiInstr::InputAt(intptr_t i) const {
321 return inputs_[i]; 324 return inputs_[i];
322 } 325 }
323 326
324 327
325 void PhiInstr::SetInputAt(intptr_t i, Value* value) { 328 void PhiInstr::SetInputAt(intptr_t i, Value* value) {
326 inputs_[i] = value; 329 inputs_[i] = value;
327 } 330 }
328 331
329 332
333 RawAbstractType* PhiInstr::StaticType() const {
334 // TODO(regis): Return the least upper bound of the input static types.
335 return Type::DynamicType();
336 }
337
338
330 intptr_t ParameterInstr::InputCount() const { 339 intptr_t ParameterInstr::InputCount() const {
331 return 0; 340 return 0;
332 } 341 }
333 342
334 343
335 Value* ParameterInstr::InputAt(intptr_t i) const { 344 Value* ParameterInstr::InputAt(intptr_t i) const {
336 UNREACHABLE(); 345 UNREACHABLE();
337 return NULL; 346 return NULL;
338 } 347 }
339 348
340 349
341 void ParameterInstr::SetInputAt(intptr_t i, Value* value) { 350 void ParameterInstr::SetInputAt(intptr_t i, Value* value) {
342 UNREACHABLE(); 351 UNREACHABLE();
343 } 352 }
344 353
345 354
355 RawAbstractType* ParameterInstr::StaticType() const {
356 // TODO(regis): Can type feedback provide information about the static type
357 // of a passed-in parameter?
358 // Note that in checked mode, we could return the static type of the formal
359 // parameter. However, this would be wrong if ParameterInstr is used to type
360 // check the passed-in parameter, since the type check would then always be
361 // wrongly eliminated.
362 return Type::DynamicType();
363 }
364
365
346 intptr_t GraphEntryInstr::InputCount() const { 366 intptr_t GraphEntryInstr::InputCount() const {
347 return 0; 367 return 0;
348 } 368 }
349 369
350 370
351 Value* GraphEntryInstr::InputAt(intptr_t i) const { 371 Value* GraphEntryInstr::InputAt(intptr_t i) const {
352 UNREACHABLE(); 372 UNREACHABLE();
353 return NULL; 373 return NULL;
354 } 374 }
355 375
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after
643 } 663 }
644 } 664 }
645 665
646 666
647 RawAbstractType* UseVal::StaticType() const { 667 RawAbstractType* UseVal::StaticType() const {
648 return definition()->StaticType(); 668 return definition()->StaticType();
649 } 669 }
650 670
651 671
652 RawAbstractType* AssertAssignableComp::StaticType() const { 672 RawAbstractType* AssertAssignableComp::StaticType() const {
673 const AbstractType& value_static_type =
674 AbstractType::Handle(value()->StaticType());
675 if (value_static_type.IsMoreSpecificThan(dst_type(), NULL)) {
676 return value_static_type.raw();
677 }
653 return dst_type().raw(); 678 return dst_type().raw();
654 } 679 }
655 680
656 681
657 RawAbstractType* AssertBooleanComp::StaticType() const { 682 RawAbstractType* AssertBooleanComp::StaticType() const {
658 return Type::BoolInterface(); 683 return Type::BoolInterface();
659 } 684 }
660 685
661 686
662 RawAbstractType* CurrentContextComp::StaticType() const { 687 RawAbstractType* CurrentContextComp::StaticType() const {
(...skipping 11 matching lines...) Expand all
674 RawAbstractType* ClosureCallComp::StaticType() const { 699 RawAbstractType* ClosureCallComp::StaticType() const {
675 // Because of function subtyping rules, the static return type of a closure 700 // Because of function subtyping rules, the static return type of a closure
676 // call cannot be relied upon for static type analysis. For example, a 701 // call cannot be relied upon for static type analysis. For example, a
677 // function returning Dynamic can be assigned to a closure variable declared 702 // function returning Dynamic can be assigned to a closure variable declared
678 // to return int and may actually return a double at run-time. 703 // to return int and may actually return a double at run-time.
679 return Type::DynamicType(); 704 return Type::DynamicType();
680 } 705 }
681 706
682 707
683 RawAbstractType* InstanceCallComp::StaticType() const { 708 RawAbstractType* InstanceCallComp::StaticType() const {
709 // TODO(regis): Return a more specific type than Dynamic for recognized
710 // combinations of receiver static type and method name.
684 return Type::DynamicType(); 711 return Type::DynamicType();
685 } 712 }
686 713
687 714
688 RawAbstractType* PolymorphicInstanceCallComp::StaticType() const { 715 RawAbstractType* PolymorphicInstanceCallComp::StaticType() const {
689 return Type::DynamicType(); 716 return Type::DynamicType();
690 } 717 }
691 718
692 719
693 RawAbstractType* StaticCallComp::StaticType() const { 720 RawAbstractType* StaticCallComp::StaticType() const {
694 return function().result_type(); 721 return function().result_type();
695 } 722 }
696 723
697 724
698 RawAbstractType* LoadLocalComp::StaticType() const { 725 RawAbstractType* LoadLocalComp::StaticType() const {
699 return local().type().raw(); 726 // TODO(regis): Verify that the type of the receiver is properly set.
727 if (FLAG_enable_type_checks) {
728 return local().type().raw();
729 }
730 return Type::DynamicType();
700 } 731 }
701 732
702 733
703 RawAbstractType* StoreLocalComp::StaticType() const { 734 RawAbstractType* StoreLocalComp::StaticType() const {
704 const AbstractType& assigned_value_type = 735 return value()->StaticType();
705 AbstractType::Handle(value()->StaticType());
706 if (assigned_value_type.IsDynamicType()) {
707 // Static type of assigned value is unknown, return static type of local.
708 return local().type().raw();
709 }
710 return assigned_value_type.raw();
711 } 736 }
712 737
713 738
714 RawAbstractType* StrictCompareComp::StaticType() const { 739 RawAbstractType* StrictCompareComp::StaticType() const {
715 return Type::BoolInterface(); 740 return Type::BoolInterface();
716 } 741 }
717 742
718 743
719 RawAbstractType* EqualityCompareComp::StaticType() const { 744 RawAbstractType* EqualityCompareComp::StaticType() const {
720 return Type::BoolInterface(); 745 return Type::BoolInterface();
(...skipping 23 matching lines...) Expand all
744 return AbstractType::null(); 769 return AbstractType::null();
745 } 770 }
746 771
747 772
748 RawAbstractType* InstanceSetterComp::StaticType() const { 773 RawAbstractType* InstanceSetterComp::StaticType() const {
749 return value()->StaticType(); 774 return value()->StaticType();
750 } 775 }
751 776
752 777
753 RawAbstractType* StaticSetterComp::StaticType() const { 778 RawAbstractType* StaticSetterComp::StaticType() const {
754 const AbstractType& assigned_value_type = 779 return value()->StaticType();
755 AbstractType::Handle(value()->StaticType());
756 if (assigned_value_type.IsDynamicType()) {
757 // Static type of assigned value is unknown, return static type of setter
758 // value parameter.
759 return setter_function().ParameterTypeAt(0);
760 }
761 return assigned_value_type.raw();
762 } 780 }
763 781
764 782
765 RawAbstractType* LoadInstanceFieldComp::StaticType() const { 783 RawAbstractType* LoadInstanceFieldComp::StaticType() const {
766 return field().type(); 784 if (FLAG_enable_type_checks) {
785 return field().type();
786 }
787 return Type::DynamicType();
767 } 788 }
768 789
769 790
770 RawAbstractType* StoreInstanceFieldComp::StaticType() const { 791 RawAbstractType* StoreInstanceFieldComp::StaticType() const {
771 const AbstractType& assigned_value_type = 792 return value()->StaticType();
772 AbstractType::Handle(value()->StaticType());
773 if (assigned_value_type.IsDynamicType()) {
774 // Static type of assigned value is unknown, return static type of field.
775 return field().type();
776 }
777 return assigned_value_type.raw();
778 } 793 }
779 794
780 795
781 RawAbstractType* LoadStaticFieldComp::StaticType() const { 796 RawAbstractType* LoadStaticFieldComp::StaticType() const {
782 return field().type(); 797 if (FLAG_enable_type_checks) {
798 return field().type();
799 }
800 return Type::DynamicType();
783 } 801 }
784 802
785 803
786 RawAbstractType* StoreStaticFieldComp::StaticType() const { 804 RawAbstractType* StoreStaticFieldComp::StaticType() const {
787 const AbstractType& assigned_value_type = 805 return value()->StaticType();
788 AbstractType::Handle(value()->StaticType());
789 if (assigned_value_type.IsDynamicType()) {
790 // Static type of assigned value is unknown, return static type of field.
791 return field().type();
792 }
793 return assigned_value_type.raw();
794 } 806 }
795 807
796 808
797 RawAbstractType* BooleanNegateComp::StaticType() const { 809 RawAbstractType* BooleanNegateComp::StaticType() const {
798 return Type::BoolInterface(); 810 return Type::BoolInterface();
799 } 811 }
800 812
801 813
802 RawAbstractType* InstanceOfComp::StaticType() const { 814 RawAbstractType* InstanceOfComp::StaticType() const {
803 return Type::BoolInterface(); 815 return Type::BoolInterface();
(...skipping 25 matching lines...) Expand all
829 } 841 }
830 842
831 843
832 RawAbstractType* LoadVMFieldComp::StaticType() const { 844 RawAbstractType* LoadVMFieldComp::StaticType() const {
833 ASSERT(!type().IsNull()); 845 ASSERT(!type().IsNull());
834 return type().raw(); 846 return type().raw();
835 } 847 }
836 848
837 849
838 RawAbstractType* StoreVMFieldComp::StaticType() const { 850 RawAbstractType* StoreVMFieldComp::StaticType() const {
839 ASSERT(!type().IsNull()); 851 return value()->StaticType();
840 const AbstractType& assigned_value_type =
841 AbstractType::Handle(value()->StaticType());
842 if (assigned_value_type.IsDynamicType()) {
843 // Static type of assigned value is unknown, return static type of field.
844 return type().raw();
845 }
846 return assigned_value_type.raw();
847 } 852 }
848 853
849 854
850 RawAbstractType* InstantiateTypeArgumentsComp::StaticType() const { 855 RawAbstractType* InstantiateTypeArgumentsComp::StaticType() const {
851 UNREACHABLE(); 856 UNREACHABLE();
852 return AbstractType::null(); 857 return AbstractType::null();
853 } 858 }
854 859
855 860
856 RawAbstractType* ExtractConstructorTypeArgumentsComp::StaticType() const { 861 RawAbstractType* ExtractConstructorTypeArgumentsComp::StaticType() const {
(...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after
1343 if (compiler->is_ssa()) { 1348 if (compiler->is_ssa()) {
1344 ASSERT(locs()->in(0).IsRegister()); 1349 ASSERT(locs()->in(0).IsRegister());
1345 __ PushRegister(locs()->in(0).reg()); 1350 __ PushRegister(locs()->in(0).reg());
1346 } 1351 }
1347 } 1352 }
1348 1353
1349 1354
1350 #undef __ 1355 #undef __
1351 1356
1352 } // namespace dart 1357 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/intermediate_language.h ('k') | runtime/vm/object.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698