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

Side by Side Diff: src/compiler/typer.cc

Issue 714413004: [turbofan] More useful typing for And, Or and Shr. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix the range/bitset subtyping mess-up in bitwise or. Created 6 years, 1 month 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 | « src/compiler/change-lowering.cc ('k') | test/cctest/compiler/test-changes-lowering.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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/bootstrapper.h" 5 #include "src/bootstrapper.h"
6 #include "src/compiler/graph-inl.h" 6 #include "src/compiler/graph-inl.h"
7 #include "src/compiler/js-operator.h" 7 #include "src/compiler/js-operator.h"
8 #include "src/compiler/node.h" 8 #include "src/compiler/node.h"
9 #include "src/compiler/node-properties-inl.h" 9 #include "src/compiler/node-properties-inl.h"
10 #include "src/compiler/node-properties.h" 10 #include "src/compiler/node-properties.h"
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after
710 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) { 710 Type* Typer::Visitor::JSBitwiseOrTyper(Type* lhs, Type* rhs, Typer* t) {
711 Factory* f = t->isolate()->factory(); 711 Factory* f = t->isolate()->factory();
712 lhs = NumberToInt32(ToNumber(lhs, t), t); 712 lhs = NumberToInt32(ToNumber(lhs, t), t);
713 rhs = NumberToInt32(ToNumber(rhs, t), t); 713 rhs = NumberToInt32(ToNumber(rhs, t), t);
714 double lmin = lhs->Min(); 714 double lmin = lhs->Min();
715 double rmin = rhs->Min(); 715 double rmin = rhs->Min();
716 double lmax = lhs->Max(); 716 double lmax = lhs->Max();
717 double rmax = rhs->Max(); 717 double rmax = rhs->Max();
718 // Or-ing any two values results in a value no smaller than their minimum. 718 // Or-ing any two values results in a value no smaller than their minimum.
719 // Even no smaller than their maximum if both values are non-negative. 719 // Even no smaller than their maximum if both values are non-negative.
720 Handle<Object> min = f->NewNumber( 720 double min =
721 lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin)); 721 lmin >= 0 && rmin >= 0 ? std::max(lmin, rmin) : std::min(lmin, rmin);
722 double max = Type::Signed32()->Max();
723
724 // Or-ing with 0 is essentially a conversion to int32.
725 if (rmin == 0 && rmax == 0) {
726 min = lmin;
727 max = lmax;
728 }
729 if (lmin == 0 && lmax == 0) {
730 min = rmin;
731 max = rmax;
732 }
733
722 if (lmax < 0 || rmax < 0) { 734 if (lmax < 0 || rmax < 0) {
723 // Or-ing two values of which at least one is negative results in a negative 735 // Or-ing two values of which at least one is negative results in a negative
724 // value. 736 // value.
725 Handle<Object> max = f->NewNumber(-1); 737 max = std::min(max, -1.0);
726 return Type::Range(min, max, t->zone());
727 } 738 }
728 Handle<Object> max = f->NewNumber(Type::Signed32()->Max()); 739 return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone());
729 return Type::Range(min, max, t->zone());
730 // TODO(neis): Be precise for singleton inputs, here and elsewhere. 740 // TODO(neis): Be precise for singleton inputs, here and elsewhere.
731 } 741 }
732 742
733 743
734 Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) { 744 Type* Typer::Visitor::JSBitwiseAndTyper(Type* lhs, Type* rhs, Typer* t) {
735 Factory* f = t->isolate()->factory(); 745 Factory* f = t->isolate()->factory();
736 lhs = NumberToInt32(ToNumber(lhs, t), t); 746 lhs = NumberToInt32(ToNumber(lhs, t), t);
737 rhs = NumberToInt32(ToNumber(rhs, t), t); 747 rhs = NumberToInt32(ToNumber(rhs, t), t);
738 double lmin = lhs->Min(); 748 double lmin = lhs->Min();
739 double rmin = rhs->Min(); 749 double rmin = rhs->Min();
740 double lmax = lhs->Max(); 750 double lmax = lhs->Max();
741 double rmax = rhs->Max(); 751 double rmax = rhs->Max();
752 double min = Type::Signed32()->Min();
742 // And-ing any two values results in a value no larger than their maximum. 753 // And-ing any two values results in a value no larger than their maximum.
743 // Even no larger than their minimum if both values are non-negative. 754 // Even no larger than their minimum if both values are non-negative.
744 Handle<Object> max = f->NewNumber( 755 double max =
745 lmin >= 0 && rmin >= 0 ? std::min(lmax, rmax) : std::max(lmax, rmax)); 756 lmin >= 0 && rmin >= 0 ? std::min(lmax, rmax) : std::max(lmax, rmax);
746 if (lmin >= 0 || rmin >= 0) { 757 // And-ing with a non-negative value x causes the result to be between
747 // And-ing two values of which at least one is non-negative results in a 758 // zero and x.
748 // non-negative value. 759 if (lmin >= 0) {
749 Handle<Object> min = f->NewNumber(0); 760 min = 0;
750 return Type::Range(min, max, t->zone()); 761 max = std::min(max, lmax);
751 } 762 }
752 Handle<Object> min = f->NewNumber(Type::Signed32()->Min()); 763 if (rmin >= 0) {
753 return Type::Range(min, max, t->zone()); 764 min = 0;
765 max = std::min(max, rmax);
766 }
767 return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone());
754 } 768 }
755 769
756 770
757 Type* Typer::Visitor::JSBitwiseXorTyper(Type* lhs, Type* rhs, Typer* t) { 771 Type* Typer::Visitor::JSBitwiseXorTyper(Type* lhs, Type* rhs, Typer* t) {
758 lhs = NumberToInt32(ToNumber(lhs, t), t); 772 lhs = NumberToInt32(ToNumber(lhs, t), t);
759 rhs = NumberToInt32(ToNumber(rhs, t), t); 773 rhs = NumberToInt32(ToNumber(rhs, t), t);
760 double lmin = lhs->Min(); 774 double lmin = lhs->Min();
761 double rmin = rhs->Min(); 775 double rmin = rhs->Min();
762 double lmax = lhs->Max(); 776 double lmax = lhs->Max();
763 double rmax = rhs->Max(); 777 double rmax = rhs->Max();
764 if ((lmin >= 0 && rmin >= 0) || (lmax < 0 && rmax < 0)) { 778 if ((lmin >= 0 && rmin >= 0) || (lmax < 0 && rmax < 0)) {
765 // Xor-ing negative or non-negative values results in a non-negative value. 779 // Xor-ing negative or non-negative values results in a non-negative value.
766 return t->non_negative_signed32; 780 return t->non_negative_signed32;
767 } 781 }
768 if ((lmax < 0 && rmin >= 0) || (lmin >= 0 && rmax < 0)) { 782 if ((lmax < 0 && rmin >= 0) || (lmin >= 0 && rmax < 0)) {
769 // Xor-ing a negative and a non-negative value results in a negative value. 783 // Xor-ing a negative and a non-negative value results in a negative value.
770 return t->negative_signed32; 784 return t->negative_signed32;
771 } 785 }
772 return Type::Signed32(); 786 return Type::Signed32();
773 } 787 }
774 788
775 789
776 Type* Typer::Visitor::JSShiftLeftTyper(Type* lhs, Type* rhs, Typer* t) { 790 Type* Typer::Visitor::JSShiftLeftTyper(Type* lhs, Type* rhs, Typer* t) {
777 return Type::Signed32(); 791 return Type::Signed32();
778 } 792 }
779 793
780 794
781 Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) { 795 Type* Typer::Visitor::JSShiftRightTyper(Type* lhs, Type* rhs, Typer* t) {
782 lhs = NumberToInt32(ToNumber(lhs, t), t); 796 lhs = NumberToInt32(ToNumber(lhs, t), t);
783 Factory* f = t->isolate()->factory(); 797 rhs = NumberToUint32(ToNumber(rhs, t), t);
798 double min = kMinInt;
799 double max = kMaxInt;
784 if (lhs->Min() >= 0) { 800 if (lhs->Min() >= 0) {
785 // Right-shifting a non-negative value cannot make it negative, nor larger. 801 // Right-shifting a non-negative value cannot make it negative, nor larger.
786 Handle<Object> min = f->NewNumber(0); 802 min = std::max(min, 0.0);
787 Handle<Object> max = f->NewNumber(lhs->Max()); 803 max = std::min(max, lhs->Max());
788 return Type::Range(min, max, t->zone());
789 } 804 }
790 if (lhs->Max() < 0) { 805 if (lhs->Max() < 0) {
791 // Right-shifting a negative value cannot make it non-negative, nor smaller. 806 // Right-shifting a negative value cannot make it non-negative, nor smaller.
792 Handle<Object> min = f->NewNumber(lhs->Min()); 807 min = std::max(min, lhs->Min());
793 Handle<Object> max = f->NewNumber(-1); 808 max = std::min(max, -1.0);
794 return Type::Range(min, max, t->zone()); 809 }
810 if (rhs->Min() > 0 && rhs->Max() <= 31) {
811 // Right-shifting by a positive value yields a small integer value.
812 double shift_min = kMinInt >> static_cast<int>(rhs->Min());
813 double shift_max = kMaxInt >> static_cast<int>(rhs->Min());
814 min = std::max(min, shift_min);
815 max = std::min(max, shift_max);
816 }
817 // TODO(jarin) Ideally, the following micro-optimization should be performed
818 // by the type constructor.
819 if (max != Type::Signed32()->Max() || min != Type::Signed32()->Min()) {
820 Factory* f = t->isolate()->factory();
821 return Type::Range(f->NewNumber(min), f->NewNumber(max), t->zone());
795 } 822 }
796 return Type::Signed32(); 823 return Type::Signed32();
797 } 824 }
798 825
799 826
800 Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) { 827 Type* Typer::Visitor::JSShiftRightLogicalTyper(Type* lhs, Type* rhs, Typer* t) {
801 lhs = NumberToUint32(ToNumber(lhs, t), t); 828 lhs = NumberToUint32(ToNumber(lhs, t), t);
802 Factory* f = t->isolate()->factory(); 829 Factory* f = t->isolate()->factory();
803 // Logical right-shifting any value cannot make it larger. 830 // Logical right-shifting any value cannot make it larger.
804 Handle<Object> min = f->NewNumber(0); 831 Handle<Object> min = f->NewNumber(0);
(...skipping 1128 matching lines...) Expand 10 before | Expand all | Expand 10 after
1933 return typer_->float64_array_fun_; 1960 return typer_->float64_array_fun_;
1934 } 1961 }
1935 } 1962 }
1936 } 1963 }
1937 return Type::Constant(value, zone()); 1964 return Type::Constant(value, zone());
1938 } 1965 }
1939 1966
1940 } 1967 }
1941 } 1968 }
1942 } // namespace v8::internal::compiler 1969 } // namespace v8::internal::compiler
OLDNEW
« no previous file with comments | « src/compiler/change-lowering.cc ('k') | test/cctest/compiler/test-changes-lowering.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698